summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2023-04-15 20:13:49 -0700
committeryum <yum.food.vr@gmail.com>2023-04-15 20:13:49 -0700
commitad7e60eb3f63c492c1ddcbcf7be8279257015c27 (patch)
tree29f4daf51e2cc01a9f3ca7acac35ae8c1c5ae672
parent273a3ab97da0aa543e970ce5c45908ee89c2f632 (diff)
Add scaling to avatar cloning shader
Scaled clones need to be manually offset so their feet are located at the ground. Add a float and a toggle for this (_Clone_Av_Height_Fix). Add ability to rotate clones along with the avatar, which is desirable in some situations. Add 1/100 scale dx parameter, useful for fine-tuning position in game.
-rw-r--r--Shaders/avatar_clone/avatar_clone.shader11
-rw-r--r--Shaders/avatar_clone/avatar_clone_lighting.cginc53
2 files changed, 47 insertions, 17 deletions
diff --git a/Shaders/avatar_clone/avatar_clone.shader b/Shaders/avatar_clone/avatar_clone.shader
index 709a301..768a3c2 100644
--- a/Shaders/avatar_clone/avatar_clone.shader
+++ b/Shaders/avatar_clone/avatar_clone.shader
@@ -29,9 +29,14 @@ Shader "yum_food/avatar_clone"
_Center_Out_Max_Radius("Center out max radius", float) = 2.7
[IntRange] _Num_Clones("Number of clones", Range(0, 4)) = 0
- _Clone_dx("Clone 0 dx", float) = 1.0
- _Clone_dy("Clone 0 dy", float) = 0.0
- _Clone_dz("Clone 0 dz", float) = 0.0
+ _Clone_dx("Clone dx", float) = 1.0
+ _Clone_dx_cents("Clone dx (cents)", float) = 0.0
+ _Clone_dy("Clone dy", float) = 0.0
+ _Clone_dz("Clone dz", float) = 0.0
+ _Clone_Scale("Clone scale", float) = 1.0
+ [ToggleUI] _Clone_Enable_Av_Height_Fix("Clone avatar height fix", float) = 0.0
+ _Clone_Av_Height_Fix("Clone avatar height fix", float) = 0.0
+ [ToggleUI] _Clone_Enable_Rotation("Enable clone rotation", float) = 0.0
}
SubShader
{
diff --git a/Shaders/avatar_clone/avatar_clone_lighting.cginc b/Shaders/avatar_clone/avatar_clone_lighting.cginc
index 7471157..c7e3478 100644
--- a/Shaders/avatar_clone/avatar_clone_lighting.cginc
+++ b/Shaders/avatar_clone/avatar_clone_lighting.cginc
@@ -37,8 +37,13 @@ float _Center_Out_Max_Radius;
float _Num_Clones;
float _Clone_dx;
+float _Clone_dx_cents;
float _Clone_dy;
float _Clone_dz;
+float _Clone_Scale;
+float _Clone_Enable_Av_Height_Fix;
+float _Clone_Av_Height_Fix;
+float _Clone_Enable_Rotation;
struct appdata
{
@@ -210,12 +215,12 @@ void geom(triangle v2f tri_in[3],
// Math from here:
// http://tonfilm.blogspot.com/2007/01/calculate-normals-in-shader.html
- for (uint i = 0; i < 3; i++) {
- v2f v0 = tri_in[(i + 0) % 3];
- v2f v1 = tri_in[(i + 1) % 3];
- v2f v2 = tri_in[(i + 2) % 3];
+ if (!_Disable_Normal_Recalc) {
+ for (uint i = 0; i < 3; i++) {
+ v2f v0 = tri_in[(i + 0) % 3];
+ v2f v1 = tri_in[(i + 1) % 3];
+ v2f v2 = tri_in[(i + 2) % 3];
- if (!_Disable_Normal_Recalc) {
float3 aa_normal = 0;
aa_normal += getNormal(v0, v1, v2, 0.3);
aa_normal += getNormal(v0, v1, v2, 0.4);
@@ -239,23 +244,43 @@ void geom(triangle v2f tri_in[3],
tri_out.Append(t2);
tri_out.RestartStrip();
+ float4x4 object_rotate = float4x4(
+ unity_ObjectToWorld[0].xyz, 0,
+ 0, 1, 0, 0,
+ unity_ObjectToWorld[2].xyz, 0,
+ 0, 0, 0, 1
+ );
+ float3 object_offset = transpose(unity_ObjectToWorld)[3].xyz;
+
const int num_clones = max((int) floor(_Num_Clones), 0);
for (int i = 2; i < num_clones + 2; i++) {
v2f t0p = t0;
v2f t1p = t1;
v2f t2p = t2;
- t0p.worldPos.x += _Clone_dx * (i / 2) * (i % 2 == 0 ? 1.0 : -1.0);
- t0p.worldPos.y += _Clone_dy * (i / 2);
- t0p.worldPos.z += _Clone_dz * (i / 2);
+ float3 dpos = 0;
+
+ if (_Clone_Enable_Av_Height_Fix) {
+ dpos.y += _Clone_Av_Height_Fix * pow(_Clone_Scale, i / 2) - object_offset.y;
+ }
+
+ dpos.x += (_Clone_dx + _Clone_dx_cents * 0.01) * (i / 2) * (i % 2 == 0 ? 1.0 : -1.0);
+ dpos.y += _Clone_dy * (i / 2);
+ dpos.z += _Clone_dz * (i / 2);
+
+ if (_Clone_Enable_Rotation) {
+ dpos = mul(object_rotate, float4(dpos, 1.0));
+ }
- t1p.worldPos.x += _Clone_dx * (i / 2) * (i % 2 == 0 ? 1.0 : -1.0);
- t1p.worldPos.y += _Clone_dy * (i / 2);
- t1p.worldPos.z += _Clone_dz * (i / 2);
+ t0p.worldPos += dpos;
+ t1p.worldPos += dpos;
+ t2p.worldPos += dpos;
- t2p.worldPos.x += _Clone_dx * (i / 2) * (i % 2 == 0 ? 1.0 : -1.0);
- t2p.worldPos.y += _Clone_dy * (i / 2);
- t2p.worldPos.z += _Clone_dz * (i / 2);
+#if 1
+ t0p.worldPos = (t0p.worldPos - (dpos + object_offset)) * pow(_Clone_Scale, i / 2) + (dpos + object_offset);
+ t1p.worldPos = (t1p.worldPos - (dpos + object_offset)) * pow(_Clone_Scale, i / 2) + (dpos + object_offset);
+ t2p.worldPos = (t2p.worldPos - (dpos + object_offset)) * pow(_Clone_Scale, i / 2) + (dpos + object_offset);
+#endif
t0p.objPos = mul(unity_WorldToObject, float4(t0p.worldPos, 1.0));
t0p.clipPos = UnityObjectToClipPos(t0p.objPos);