変形テスト pic.twitter.com/yor3hDuS5t
— 光属性のアルモジナ(VRChat勢) (@arumogina) July 29, 2019
参考
wgld.org | GLSL: オブジェクトを行列で捻じるように変換 |
Shader "Custom/Ray14"{ Properties{ _R1("R1",Float) = 0.3 _R1Origin("R1Origin",Vector) = (-0.3,0,0,0) _R1SPD("R1SPD",float) = 50 _R1AXIS("R1AXIS",Vector) = (1,0,0,0) _R1TwistPower("_R1TwistPower",Float) = 0 _R2("R2",Float) = 0.3 _R2Origin("R2Origin",Vector) = (0.3,0,0,0) _R2SPD("R2SPD",float) = 50 _R2AXIS("R2AXIS",Vector) = (1,0,0,0) _R2TwistPower("_R2TwistPower",Float) = 0 _Scale("Scale",Int) = 5 _SplitNum("SplitNum",Range(0,100)) = 30 _K("K",Range(0,70)) = 8 _Normal("Normal",Range(0,0.1)) = 0.01 _BoxTwistPower("BoxTwistPower",Range(0,80)) = 0 } SubShader{ Tags { "RenderType" = "Opaque" "LightMode" = "ForwardBase" } LOD 100 Cull Off Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" float _R1; float _R2; float _R1SPD; float _R2SPD; float4 _R1AXIS; float4 _R2AXIS; float _R1TwistPower; float _R2TwistPower; float _Scale; float4 _R1Origin; float4 _R2Origin; int _SplitNum; float _K; float _BoxTwistPower; float _Normal; struct appdata{ float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f{ float2 uv : TEXCOORD0; float3 lpos : TEXCOORD1; float3 wpos : TEXCOORD2; float4 vertex : SV_POSITION; }; v2f vert(appdata v){ v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.lpos =v.vertex.xyz;//メッシュのローカル座標を代入 o.wpos = mul(unity_ObjectToWorld,v.vertex); o.uv = v.uv; return o; } float3 twist(float3 p, float power){ float s = sin(power * p.y); float c = cos(power * p.y); float3x3 m = float3x3( c, 0.0, -s, 0.0, 1.0, 0.0, s, 0.0, c ); return mul(m,p); } float3 rotate(float3 p, float angle, float3 axis){ float3 a = normalize(axis); float s = sin(angle); float c = cos(angle); float r = 1.0 - c; float3x3 m = float3x3( a.x * a.x * r + c, a.y * a.x * r + a.z * s, a.z * a.x * r - a.y * s, a.x * a.y * r - a.z * s, a.y * a.y * r + c, a.z * a.y * r + a.x * s, a.x * a.z * r + a.y * s, a.y * a.z * r - a.x * s, a.z * a.z * r + c ); return mul(m,p); } float box(float3 p){ float s = 0.2; p = twist(p,_BoxTwistPower); return length(max(abs(p) - float3(s,s,s),0.0)); } float sphere(float3 p){ p = twist(p,_R1TwistPower); return length(p) - 0.4; } float sphere1(float3 p){ p = rotate(p, radians(_Time.y * _R1SPD), _R1AXIS.xyz); p = twist(p,_R1TwistPower); return length(p-_R1Origin) - _R1; } float sphere2(float3 p){ p = rotate(p, radians(_Time.y * _R2SPD), _R2AXIS.xyz); p = twist(p,_R2TwistPower); return length(p-_R2Origin) - _R2; } float3 mod(float3 a, float3 b){ return frac(abs(a / b)) * abs(b); } float3 trans(float3 p){ return mod(p, _Scale) - _Scale/2.0; } float smoothMin(float d1, float d2, float k){ float h = exp(-k * d1) + exp(-k * d2); return -log(h) / k; } float dist(float3 p){ //return sphere(p); return box(p); //return sphere1(p); //return smoothMin(sphere1(p),sphere2(p),_K); //return min(sphere1(p),sphere2(p)); //return length(trans(p-_Origin)) - _R; } float3 getnormal(float3 p){ //float d = 0.0001; float d= _Normal; return normalize(float3( dist(p + float3(d, 0.0, 0.0)) - dist(p + float3(-d, 0.0, 0.0)), dist(p + float3(0.0, d, 0.0)) - dist(p + float3(0.0, -d, 0.0)), dist(p + float3(0.0, 0.0, d)) - dist(p + float3(0.0, 0.0, -d)) )); } fixed4 frag(v2f i) : SV_Target{ //メッシュのローカル座標の、視点のローカル座標からの方向を求めることでレイの方向を定義 float3 start = mul(unity_WorldToObject,float4(_WorldSpaceCameraPos,1)).xyz;//レイのスタート位置をカメラのローカル座標とする float3 onelay = normalize(i.lpos.xyz - mul(unity_WorldToObject,float4(_WorldSpaceCameraPos,1)).xyz); float d =0; float t=0.001; for (int i = 0; i < _SplitNum; ++i) { //レイマーチのループを実行 d = dist(start + onelay * t); t += d; //レイがどこにもぶつからずはるか遠くに行くか、ほぼ衝突していて進む距離がほとんどなくなったらループを終了する if (d < 0.01 || t > 1000) { break; } } float4 col = 1; if (d > 0.01||t>1000) { //レイが遠くに行っているか、衝突していないと判断すれば描画しない clip(-1); } else { float3 normal = getnormal(start+onelay * t); float3 lightdir = normalize(mul(unity_WorldToObject, _WorldSpaceLightPos0).xyz);//オブジェクトスペースで計算しているので、ディレクショナルライトの角度もオブジェクトスペースにする float NdotL = max(0, dot(normal, lightdir)); col = float4(float3(1,1,1)*NdotL,1);//ランバート反射を計算 } return col; } ENDCG }//pass }//subshader }