実現したいもの
public class Move1 : MonoBehaviour { public float speed = 0.1f; float moveX = 0f; float moveZ = 0f; CharacterController controller; void Start(){ controller = GetComponent<CharacterController>(); } void Update() { moveX = Input.GetAxisRaw ("Horizontal") * speed; moveZ = Input.GetAxisRaw ("Vertical") * speed; Vector3 direction = new Vector3(moveX , 0, moveZ); controller.Move(direction); } }
これをこの状態のまま(rotationが45のまま)、向きも変わるようにしたいんです。
試したこと1
一応、無料アセットStandardAssetsに付いてくるThirdPersonControllerで
・付属のThirdPersonUserController componentを無効化
・MainCameraのタグをUnTaggedに
・以下の移動用Scriptを作成
namespace UnityStandardAssets.Characters.ThirdPerson { [RequireComponent(typeof (ThirdPersonCharacter))] public class Move2 : MonoBehaviour { private ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object private Transform m_Cam; // A reference to the main camera in the scenes transform private Vector3 m_CamForward; // The current forward direction of the camera private Vector3 m_Move; private bool m_Jump; // the world-relative desired move direction, calculated from the camForward and user input. private void Start() { // get the third person character ( this should never be null due to require component ) m_Character = GetComponent<ThirdPersonCharacter>(); } private void Update() { } // Fixed update is called in sync with physics private void FixedUpdate() { // read inputs float h = Input.GetAxisRaw("Horizontal"); float v = Input.GetAxisRaw("Vertical"); bool crouch = Input.GetKey(KeyCode.C); // キャラ操作の前後左右をカメラの方向に合わせる // 入力値をそのままキャラクターの移動方向として処理する m_Move = v*Vector3.forward + h*Vector3.right; // pass all parameters to the character control script m_Character.Move(m_Move, crouch, m_Jump); m_Jump = false; } } }
すると、こんな感じで理想に近いものにはなるんですが(画像2)
これだと
・移動したい方向に向き切らないと進まない
・画像1と違って若干移動速度が一定ではないように見える(一定速度でもっとスーッと動かしたい)
・上下に動く時は遅くなってしまう
で、理想とはちょっと違うんです。
この動きの原因は恐らくファンクションとして使っている付属のThirdPersonCharacter.csの中にあると思うのですが
(文字数制限なので入れられませんでした)
http://coding-reptile.hateblo.jp/entry/2016/11/07/023330
ここの解説を見ても、どこを弄れば理想の動きになるのか分からず苦戦してます。
出来ればThirdPersonCharacter.csの中から必要な要素だけを取り出してスッキリさせたいのですが…
試したこと2
CharaconをやめてRigidbodyで。transform.upで回転軸を指定。
public class move2 : MonoBehaviour { public float speed = 1f; private Vector3 Player_pos; private float x; private float z; private Rigidbody rigd; void Start() { Player_pos = GetComponent<Transform>().position; //プレイヤーのポジションを取得 rigd = GetComponent<Rigidbody>(); } void Update() { x = Input.GetAxisRaw("Horizontal"); z = Input.GetAxisRaw("Vertical"); rigd.velocity = new Vector3(x * speed, 0, z * speed); Vector3 diff = transform.position - Player_pos; //初期位置と現在地の座標差分を取得 if (diff.magnitude > 0.01f) { transform.rotation = Quaternion.LookRotation(diff ,transform.up);//プレイヤーを回転 } Player_pos = transform.position; } }
結果は画像3
左右は希望通りの動きをしますが、前後入力すると強制的に傾き完全矯正
更に、1回斜め入力を入れるごとに、半分ずつ?ぐらいに傾きが小さくなっていきます(画像4)
試したこと3
ThirdPersonCharacter.csの解読を一旦諦め、
https://gomafrontier.com/unity/2883
こちらの考えをほぼそのまま流用し、傾き45のまま対象に向かせるものを試作してみました。
高低差が無くなっただけで、対象との位置関係とかは同じように考えられるはずなんですが、画像5のように、傾きが自動矯正されてしまいます。(Z軸X軸はちゃんと無視してくれてます)
色んな方法を探していますが、どうも原理が良く分かりません
どうかアドバイスを下さい。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
Tilter改造案1
視界をひずめるのをビュー行列の代わりにプロジェクション行列で行うようにしてみました。旧Tilter
よりも少々行列計算の回数が増えてしまいました...
C#
1using UnityEngine; 2 3[RequireComponent(typeof(Camera))] 4public class Tilter : MonoBehaviour 5{ 6 [SerializeField][Range(-45.0f, 45.0f)] private float angle = 45.0f; 7 private new Camera camera; 8 9 private void Awake() 10 { 11 this.camera = this.GetComponent<Camera>(); 12 } 13 14 private void OnPreCull() 15 { 16 var theta = this.angle * Mathf.Deg2Rad; 17 var tiltMatrix = Matrix4x4.identity; 18 tiltMatrix[5] = Mathf.Cos(theta); 19 tiltMatrix[6] = Mathf.Sin(theta); 20 this.camera.ResetProjectionMatrix(); 21 this.camera.projectionMatrix *= this.camera.worldToCameraMatrix * tiltMatrix * this.camera.cameraToWorldMatrix; 22 } 23}
Tilter改造案2
案1でやっていることをAwake
で1回だけ行うパターンです。
実行中の負荷はより小さいと思いますが、プレイモード中にプロジェクション関連のパラメーターを操作する...Projectionモードを変えたり、SizeやClipping Planesを変えたりすると、ひずみがリセットされてしまいます。また、プレイモード中にTilter
のAngle
を変えてもひずみ量は変わりません。さらにAwake
時点でのビュー行列をプロジェクション行列ひずめに使っている都合上、プレイモード中にカメラを回転させるとひずみ方が奇妙になってしまう欠点もあります。平行移動するだけなら多分大丈夫だと思うのですが...
C#
1using UnityEngine; 2 3[RequireComponent(typeof(Camera))] 4public class Tilter : MonoBehaviour 5{ 6 [SerializeField][Range(-45.0f, 45.0f)] private float angle = 45.0f; 7 8 private void Awake() 9 { 10 var camera = this.GetComponent<Camera>(); 11 var theta = this.angle * Mathf.Deg2Rad; 12 var tiltMatrix = Matrix4x4.identity; 13 tiltMatrix[5] = Mathf.Cos(theta); 14 tiltMatrix[6] = Mathf.Sin(theta); 15 camera.projectionMatrix *= camera.worldToCameraMatrix * tiltMatrix * camera.cameraToWorldMatrix; 16 } 17}
投稿2019/09/25 16:40
総合スコア10811
0
ベストアンサー
「試したこと1」の問題点をなんとか修正できないかと思って調べてみました。
「移動したい方向に向き切らないと進まない」について
転回速度を調整するともっさり感が改善するんじゃないかと思います。
ThirdPersonCharacter
のインスペクター上で「Moving Turn Speed」と「Stationary Turn Speed」をもっと上げて、720とか1440にしてみてはいかがでしょう。
「画像1と違って若干移動速度が一定ではないように見える」について
ブレンドツリーによるモーション間の遷移にdampTime
が設定されており、一瞬で目的のモーションに遷移するわけではないことによるのかもしれません。
転回速度の調整だけでもだいぶ応答性がよくなるかと思いますが、まだ足りなければThirdPersonCharacter
を下記のように少し改造して、ダンプ処理を無効化してみてはどうでしょうか。
C#
1using UnityEngine; 2 3namespace UnityStandardAssets.Characters.ThirdPerson 4{ 5 [RequireComponent(typeof(Rigidbody))] 6 [RequireComponent(typeof(CapsuleCollider))] 7 [RequireComponent(typeof(Animator))] 8 public class ThirdPersonCharacter : MonoBehaviour 9 { 10 // ここまで変更なしのため省略 11 12 void UpdateAnimator(Vector3 move) 13 { 14 // update the animator parameters 15 16 // ここの2行を... 17 /* 18 m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime); 19 m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime); 20 */ 21 22 // このようにして、アニメーションのForwardとTurnが即座に目標値に到達するようにしてみる 23 m_Animator.SetFloat("Forward", m_ForwardAmount); 24 m_Animator.SetFloat("Turn", m_TurnAmount); 25 26 // 残りは変更なしのため省略 27 } 28 29 // 残りは変更なしのため省略 30 } 31}
「上下に動く時は遅くなってしまう」について
ThirdPersonCharacter
のMove
メソッドをご覧いただきますと、入力された移動ベクトルをキャラクターローカルの向きに変換して使用していることがお分かりいただけるかと思います。キャラクターが45°傾けられているので、キャラクターにとっては45°の坂道を上り下りしているような気分かもしれません。
Move2
スクリプトでStart
時点のキャラクターの回転を覚えておき、Move
実行の際に渡すm_Move
を初期回転分だけ回してやってはいかがでしょう。
C#
1using UnityEngine; 2 3namespace UnityStandardAssets.Characters.ThirdPerson 4{ 5 [RequireComponent(typeof (ThirdPersonCharacter))] 6 public class Move2 : MonoBehaviour 7 { 8 private ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object 9 private Transform m_Cam; // A reference to the main camera in the scenes transform 10 private Vector3 m_CamForward; // The current forward direction of the camera 11 private Vector3 m_Move; 12 private bool m_Jump; // the world-relative desired move direction, calculated from the camForward and user input. 13 private Quaternion m_InitialRotation; // The rotation of the transform at the Start 14 15 private void Start() 16 { 17 // get the third person character ( this should never be null due to require component ) 18 m_Character = GetComponent<ThirdPersonCharacter>(); 19 m_InitialRotation = transform.rotation; 20 } 21 22 23 private void Update() { 24 25 } 26 27 28 // Fixed update is called in sync with physics 29 private void FixedUpdate() 30 { 31 // read inputs 32 float h = Input.GetAxisRaw("Horizontal"); 33 float v = Input.GetAxisRaw("Vertical"); 34 bool crouch = Input.GetKey(KeyCode.C); 35 36 // キャラ操作の前後左右をカメラの方向に合わせる 37 // 入力値をそのままキャラクターの移動方向として処理する 38 m_Move = v*Vector3.forward + h*Vector3.right; 39 40 // pass all parameters to the character control script 41 m_Character.Move(m_InitialRotation * m_Move, crouch, m_Jump); 42 m_Jump = false; 43 } 44 } 45}
上記の3点を調整してみたところ、下図のような動きになりました。だいぶキビキビしたように思いますが、いかがでしょうか?
「上下に動く時は遅くなってしまう」について追記
すいません、前後方向の速さ調整が不十分で、水平方向よりも遅くなっていました。付け焼き刃ですがThirdPersonCharacter
を下記のようにして、
C#
1using UnityEngine; 2 3namespace UnityStandardAssets.Characters.ThirdPerson 4{ 5 [RequireComponent(typeof(Rigidbody))] 6 [RequireComponent(typeof(CapsuleCollider))] 7 [RequireComponent(typeof(Animator))] 8 public class ThirdPersonCharacter : MonoBehaviour 9 { 10 public Vector2 MoveSpeedMultiplier2D { get; set; } = Vector2.one; // プロパティを追加 11 12 // 省略 13 14 public void OnAnimatorMove() 15 { 16 // we implement this function to override the default root motion. 17 // this allows us to modify the positional speed before it's applied. 18 if (m_IsGrounded && Time.deltaTime > 0) 19 { 20 // X、Zに追加の速度調整を行う 21 Vector3 v = Vector3.Scale(m_Animator.deltaPosition, new Vector3(MoveSpeedMultiplier2D.x, 0.0f, MoveSpeedMultiplier2D.y)) * m_MoveSpeedMultiplier / Time.deltaTime; 22 23 // we preserve the existing y part of the current velocity. 24 v.y = m_Rigidbody.velocity.y; 25 m_Rigidbody.velocity = v; 26 } 27 } 28 29 // 省略 30 } 31}
Move2
を下記のようにしました。
C#
1using UnityEngine; 2 3namespace UnityStandardAssets.Characters.ThirdPerson 4{ 5 [RequireComponent(typeof (ThirdPersonCharacter))] 6 public class Move2 : MonoBehaviour 7 { 8 private ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object 9 private Transform m_Cam; // A reference to the main camera in the scenes transform 10 private Vector3 m_CamForward; // The current forward direction of the camera 11 private Vector3 m_Move; 12 private bool m_Jump; // the world-relative desired move direction, calculated from the camForward and user input. 13 private Vector2 m_Gradient; // The gradient of the X-Z plane of the transform at the Start 14 15 private void Start() 16 { 17 // get the third person character ( this should never be null due to require component ) 18 m_Character = GetComponent<ThirdPersonCharacter>(); 19 m_Gradient = new Vector2(-transform.up.x / transform.up.y, -transform.up.z / transform.up.y); 20 } 21 22 private void Update() 23 { 24 } 25 26 // Fixed update is called in sync with physics 27 private void FixedUpdate() 28 { 29 // read inputs 30 float h = Input.GetAxisRaw("Horizontal"); 31 float v = Input.GetAxisRaw("Vertical"); 32 bool crouch = Input.GetKey(KeyCode.C); 33 34 // キャラ操作の前後左右をカメラの方向に合わせる 35 // 入力値をそのままキャラクターの移動方向として処理する 36 m_Move = v*Vector3.forward + h*Vector3.right; 37 38 // pass all parameters to the character control script 39 Vector3 move = m_Move + Vector3.up * Vector2.Dot(new Vector2(h, v), this.m_Gradient); 40 float absMoveX = Mathf.Abs(m_Move.x); 41 float absMoveZ = Mathf.Abs(m_Move.z); 42 float multiplierX = absMoveX > 0.01f ? new Vector2(move.x, move.y).magnitude / absMoveX : 1.0f; 43 float multiplierZ = absMoveZ > 0.01f ? new Vector2(move.z, move.y).magnitude / absMoveZ : 1.0f; 44 this.m_Character.MoveSpeedMultiplier2D = new Vector2(multiplierX, multiplierZ); 45 m_Character.Move(move, crouch, m_Jump); 46 m_Jump = false; 47 } 48 } 49}
何だかThirdPersonCharacter
は普通の正立したキャラクターを前提にした部分が随所にあるようで、けっこうやっかいですね...
おまけ
ご質問者さんの進めていらっしゃる45°回転方式で問題なさそうですが、オブジェクトを正立させたまま見た目だけ傾けることはできないかと思い、個人的な興味から実験してみました。
カメラに下記スクリプトを付けて視界を傾け...
C#
1using UnityEngine; 2 3[RequireComponent(typeof(Camera))] 4public class Tilter : MonoBehaviour 5{ 6 [SerializeField][Range(-45.0f, 45.0f)] private float angle = 45.0f; 7 private new Camera camera; 8 9 private void Awake() 10 { 11 this.camera = this.GetComponent<Camera>(); 12 } 13 14 private void OnPreCull() 15 { 16 var theta = this.angle * Mathf.Deg2Rad; 17 var tiltMatrix = Matrix4x4.identity; 18 tiltMatrix[5] = Mathf.Cos(theta); 19 tiltMatrix[6] = Mathf.Sin(theta); 20 this.camera.ResetWorldToCameraMatrix(); 21 this.camera.worldToCameraMatrix *= tiltMatrix; 22 } 23}
影を正常化するため、ビルトインのInternal-ScreenSpaceShadowsを一部変更したバージョンをResourcesフォルダーに入れ...
ShaderLab
1// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 3// Collects cascaded shadows into screen space buffer 4// シェーダー名をビルトインのものとかぶらないよう変更 5Shader "Hidden/Internal-ScreenSpaceShadowsForFunkyProjection" { 6 7 // ここまで変更なしのため省略 8 9 // 本来のコードはここでcomputeCameraSpacePosFromDepthを宣言するだけだが 10 // 実装を定義し常にcomputeCameraSpacePosFromDepthAndInvProjMatを使うようにする 11 inline float3 computeCameraSpacePosFromDepth(v2f i) 12 { 13 return computeCameraSpacePosFromDepthAndInvProjMat(i); 14 } 15 16 // ここまで変更なしのため省略 17 18 // 以下、各サブシェーダー内のcomputeCameraSpacePosFromDepth実装定義をすべて削除する 19 20 // ---------------------------------------------------------------------------------------- 21 // Subshader for hard shadows: 22 // Just collect shadows into the buffer. Used on pre-SM3 GPUs and when hard shadows are picked. 23 24 SubShader { 25 Tags{ "ShadowmapFilter" = "HardShadow" } 26 Pass { 27 ZWrite Off ZTest Always Cull Off 28 29 CGPROGRAM 30 #pragma vertex vert 31 #pragma fragment frag_hard 32 #pragma multi_compile_shadowcollector 33 ENDCG 34 } 35 } 36 37 // ---------------------------------------------------------------------------------------- 38 // Subshader for hard shadows: 39 // Just collect shadows into the buffer. Used on pre-SM3 GPUs and when hard shadows are picked. 40 // This version does inv projection at the PS level, slower and less precise however more general. 41 42 SubShader { 43 Tags{ "ShadowmapFilter" = "HardShadow_FORCE_INV_PROJECTION_IN_PS" } 44 Pass{ 45 ZWrite Off ZTest Always Cull Off 46 47 CGPROGRAM 48 #pragma vertex vert 49 #pragma fragment frag_hard 50 #pragma multi_compile_shadowcollector 51 ENDCG 52 } 53 } 54 55 // ---------------------------------------------------------------------------------------- 56 // Subshader that does soft PCF filtering while collecting shadows. 57 // Requires SM3 GPU. 58 59 Subshader { 60 Tags {"ShadowmapFilter" = "PCF_SOFT"} 61 Pass { 62 ZWrite Off ZTest Always Cull Off 63 64 CGPROGRAM 65 #pragma vertex vert 66 #pragma fragment frag_pcfSoft 67 #pragma multi_compile_shadowcollector 68 #pragma target 3.0 69 ENDCG 70 } 71 } 72 73 // ---------------------------------------------------------------------------------------- 74 // Subshader that does soft PCF filtering while collecting shadows. 75 // Requires SM3 GPU. 76 // This version does inv projection at the PS level, slower and less precise however more general. 77 78 Subshader{ 79 Tags{ "ShadowmapFilter" = "PCF_SOFT_FORCE_INV_PROJECTION_IN_PS" } 80 Pass{ 81 ZWrite Off ZTest Always Cull Off 82 83 CGPROGRAM 84 #pragma vertex vert 85 #pragma fragment frag_pcfSoft 86 #pragma multi_compile_shadowcollector 87 #pragma target 3.0 88 ENDCG 89 } 90 } 91 92 Fallback Off 93}
プロジェクト設定で上記シェーダーをスクリーンスペースシャドウ生成時に使用するよう設定したところ...
下図のような動きになりました。オブジェクトを剪断変形するかのようにひずめるため、45°回転方式とは違ってオブジェクトの上面が見えやすいという特徴があり、なんとなく縦に引き延ばされたように感じます。Z方向にわずかに縮めてやるとバランスがよくなるかもしれません。
投稿2019/09/22 20:25
編集2019/09/23 04:20総合スコア10811
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/23 15:30
2019/09/24 02:35
2019/09/25 07:48
2019/09/25 13:20
2019/09/25 15:14
2019/09/25 16:40
0
Internal-ScreenSpaceShadowsForFunkyProjection
省略なし、コメント削減
ShaderLab
1// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 3Shader "Hidden/Internal-ScreenSpaceShadowsForFunkyProjection" { 4 Properties { 5 _ShadowMapTexture ("", any) = "" {} 6 _ODSWorldTexture("", 2D) = "" {} 7 } 8 9 CGINCLUDE 10 11 UNITY_DECLARE_SHADOWMAP(_ShadowMapTexture); 12 float4 _ShadowMapTexture_TexelSize; 13 #define SHADOWMAPSAMPLER_AND_TEXELSIZE_DEFINED 14 sampler2D _ODSWorldTexture; 15 16 #include "UnityCG.cginc" 17 #include "UnityShadowLibrary.cginc" 18 19 #define UNITY_USE_CASCADE_BLENDING 0 20 #define UNITY_CASCADE_BLEND_DISTANCE 0.1 21 22 struct appdata { 23 float4 vertex : POSITION; 24 float2 texcoord : TEXCOORD0; 25 #ifdef UNITY_STEREO_INSTANCING_ENABLED 26 float3 ray0 : TEXCOORD1; 27 float3 ray1 : TEXCOORD2; 28 #else 29 float3 ray : TEXCOORD1; 30 #endif 31 UNITY_VERTEX_INPUT_INSTANCE_ID 32 }; 33 34 struct v2f { 35 36 float4 pos : SV_POSITION; 37 float4 uv : TEXCOORD0; 38 float3 ray : TEXCOORD1; 39 float3 orthoPosNear : TEXCOORD2; 40 float3 orthoPosFar : TEXCOORD3; 41 UNITY_VERTEX_INPUT_INSTANCE_ID 42 UNITY_VERTEX_OUTPUT_STEREO 43 }; 44 45 v2f vert (appdata v) 46 { 47 v2f o; 48 UNITY_SETUP_INSTANCE_ID(v); 49 UNITY_TRANSFER_INSTANCE_ID(v, o); 50 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); 51 float4 clipPos; 52 #if defined(STEREO_CUBEMAP_RENDER_ON) 53 clipPos = mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, v.vertex)); 54 #else 55 clipPos = UnityObjectToClipPos(v.vertex); 56 #endif 57 o.pos = clipPos; 58 o.uv.xy = v.texcoord; 59 60 o.uv.zw = ComputeNonStereoScreenPos(clipPos); 61 62 #ifdef UNITY_STEREO_INSTANCING_ENABLED 63 o.ray = unity_StereoEyeIndex == 0 ? v.ray0 : v.ray1; 64 #else 65 o.ray = v.ray; 66 #endif 67 68 clipPos.y *= _ProjectionParams.x; 69 float3 orthoPosNear = mul(unity_CameraInvProjection, float4(clipPos.x,clipPos.y,-1,1)).xyz; 70 float3 orthoPosFar = mul(unity_CameraInvProjection, float4(clipPos.x,clipPos.y, 1,1)).xyz; 71 orthoPosNear.z *= -1; 72 orthoPosFar.z *= -1; 73 o.orthoPosNear = orthoPosNear; 74 o.orthoPosFar = orthoPosFar; 75 76 return o; 77 } 78 79 UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); 80 float4 unity_ShadowCascadeScales; 81 82 #if defined (SHADOWS_SPLIT_SPHERES) 83 #define GET_CASCADE_WEIGHTS(wpos, z) getCascadeWeights_splitSpheres(wpos) 84 #else 85 #define GET_CASCADE_WEIGHTS(wpos, z) getCascadeWeights( wpos, z ) 86 #endif 87 88 #if defined (SHADOWS_SINGLE_CASCADE) 89 #define GET_SHADOW_COORDINATES(wpos,cascadeWeights) getShadowCoord_SingleCascade(wpos) 90 #else 91 #define GET_SHADOW_COORDINATES(wpos,cascadeWeights) getShadowCoord(wpos,cascadeWeights) 92 #endif 93 94 inline fixed4 getCascadeWeights(float3 wpos, float z) 95 { 96 fixed4 zNear = float4( z >= _LightSplitsNear ); 97 fixed4 zFar = float4( z < _LightSplitsFar ); 98 fixed4 weights = zNear * zFar; 99 return weights; 100 } 101 102 inline fixed4 getCascadeWeights_splitSpheres(float3 wpos) 103 { 104 float3 fromCenter0 = wpos.xyz - unity_ShadowSplitSpheres[0].xyz; 105 float3 fromCenter1 = wpos.xyz - unity_ShadowSplitSpheres[1].xyz; 106 float3 fromCenter2 = wpos.xyz - unity_ShadowSplitSpheres[2].xyz; 107 float3 fromCenter3 = wpos.xyz - unity_ShadowSplitSpheres[3].xyz; 108 float4 distances2 = float4(dot(fromCenter0,fromCenter0), dot(fromCenter1,fromCenter1), dot(fromCenter2,fromCenter2), dot(fromCenter3,fromCenter3)); 109 fixed4 weights = float4(distances2 < unity_ShadowSplitSqRadii); 110 weights.yzw = saturate(weights.yzw - weights.xyz); 111 return weights; 112 } 113 114 inline float4 getShadowCoord( float4 wpos, fixed4 cascadeWeights ) 115 { 116 float3 sc0 = mul (unity_WorldToShadow[0], wpos).xyz; 117 float3 sc1 = mul (unity_WorldToShadow[1], wpos).xyz; 118 float3 sc2 = mul (unity_WorldToShadow[2], wpos).xyz; 119 float3 sc3 = mul (unity_WorldToShadow[3], wpos).xyz; 120 float4 shadowMapCoordinate = float4(sc0 * cascadeWeights[0] + sc1 * cascadeWeights[1] + sc2 * cascadeWeights[2] + sc3 * cascadeWeights[3], 1); 121 #if defined(UNITY_REVERSED_Z) 122 float noCascadeWeights = 1 - dot(cascadeWeights, float4(1, 1, 1, 1)); 123 shadowMapCoordinate.z += noCascadeWeights; 124 #endif 125 return shadowMapCoordinate; 126 } 127 128 inline float4 getShadowCoord_SingleCascade( float4 wpos ) 129 { 130 return float4( mul (unity_WorldToShadow[0], wpos).xyz, 0); 131 } 132 133 inline float3 computeCameraSpacePosFromDepthAndInvProjMat(v2f i) 134 { 135 float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy); 136 137 #if defined(UNITY_REVERSED_Z) 138 zdepth = 1 - zdepth; 139 #endif 140 141 float4 clipPos = float4(i.uv.zw, zdepth, 1.0); 142 clipPos.xyz = 2.0f * clipPos.xyz - 1.0f; 143 float4 camPos = mul(unity_CameraInvProjection, clipPos); 144 camPos.xyz /= camPos.w; 145 camPos.z *= -1; 146 return camPos.xyz; 147 } 148 149 inline float3 computeCameraSpacePosFromDepthAndVSInfo(v2f i) 150 { 151 float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy); 152 153 float depth = lerp(Linear01Depth(zdepth), zdepth, unity_OrthoParams.w); 154 #if defined(UNITY_REVERSED_Z) 155 zdepth = 1 - zdepth; 156 #endif 157 158 float3 vposPersp = i.ray * depth; 159 float3 vposOrtho = lerp(i.orthoPosNear, i.orthoPosFar, zdepth); 160 float3 camPos = lerp(vposPersp, vposOrtho, unity_OrthoParams.w); 161 return camPos.xyz; 162 } 163 164 // computeCameraSpacePosFromDepthで常にcomputeCameraSpacePosFromDepthAndInvProjMatを使うよう変更 165 inline float3 computeCameraSpacePosFromDepth(v2f i) 166 { 167 return computeCameraSpacePosFromDepthAndInvProjMat(i); 168 } 169 170 fixed4 frag_hard (v2f i) : SV_Target 171 { 172 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); 173 float4 wpos; 174 float3 vpos; 175 176 #if defined(STEREO_CUBEMAP_RENDER_ON) 177 wpos.xyz = tex2D(_ODSWorldTexture, i.uv.xy).xyz; 178 wpos.w = 1.0f; 179 vpos = mul(unity_WorldToCamera, wpos).xyz; 180 #else 181 vpos = computeCameraSpacePosFromDepth(i); 182 wpos = mul (unity_CameraToWorld, float4(vpos,1)); 183 #endif 184 185 fixed4 cascadeWeights = GET_CASCADE_WEIGHTS (wpos, vpos.z); 186 float4 shadowCoord = GET_SHADOW_COORDINATES(wpos, cascadeWeights); 187 188 fixed shadow = UNITY_SAMPLE_SHADOW(_ShadowMapTexture, shadowCoord); 189 shadow = lerp(_LightShadowData.r, 1.0, shadow); 190 191 fixed4 res = shadow; 192 return res; 193 } 194 195 fixed4 frag_pcfSoft(v2f i) : SV_Target 196 { 197 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); 198 float4 wpos; 199 float3 vpos; 200 201 #if defined(STEREO_CUBEMAP_RENDER_ON) 202 wpos.xyz = tex2D(_ODSWorldTexture, i.uv.xy).xyz; 203 wpos.w = 1.0f; 204 vpos = mul(unity_WorldToCamera, wpos).xyz; 205 #else 206 vpos = computeCameraSpacePosFromDepth(i); 207 wpos = mul(unity_CameraToWorld, float4(vpos,1)); 208 #endif 209 210 fixed4 cascadeWeights = GET_CASCADE_WEIGHTS(wpos, vpos.z); 211 float4 coord = GET_SHADOW_COORDINATES(wpos, cascadeWeights); 212 213 float3 receiverPlaneDepthBias = 0.0; 214 #ifdef UNITY_USE_RECEIVER_PLANE_BIAS 215 float3 coordCascade0 = getShadowCoord_SingleCascade(wpos); 216 float biasMultiply = dot(cascadeWeights,unity_ShadowCascadeScales); 217 receiverPlaneDepthBias = UnityGetReceiverPlaneDepthBias(coordCascade0.xyz, biasMultiply); 218 #endif 219 220 #if defined(SHADER_API_MOBILE) 221 half shadow = UnitySampleShadowmap_PCF5x5(coord, receiverPlaneDepthBias); 222 #else 223 half shadow = UnitySampleShadowmap_PCF7x7(coord, receiverPlaneDepthBias); 224 #endif 225 shadow = lerp(_LightShadowData.r, 1.0f, shadow); 226 227 #if UNITY_USE_CASCADE_BLENDING && !defined(SHADOWS_SPLIT_SPHERES) && !defined(SHADOWS_SINGLE_CASCADE) 228 half4 z4 = (float4(vpos.z,vpos.z,vpos.z,vpos.z) - _LightSplitsNear) / (_LightSplitsFar - _LightSplitsNear); 229 half alpha = dot(z4 * cascadeWeights, half4(1,1,1,1)); 230 231 UNITY_BRANCH 232 if (alpha > 1 - UNITY_CASCADE_BLEND_DISTANCE) 233 { 234 alpha = (alpha - (1 - UNITY_CASCADE_BLEND_DISTANCE)) / UNITY_CASCADE_BLEND_DISTANCE; 235 cascadeWeights = fixed4(0, cascadeWeights.xyz); 236 coord = GET_SHADOW_COORDINATES(wpos, cascadeWeights); 237 238 #ifdef UNITY_USE_RECEIVER_PLANE_BIAS 239 biasMultiply = dot(cascadeWeights,unity_ShadowCascadeScales); 240 receiverPlaneDepthBias = UnityGetReceiverPlaneDepthBias(coordCascade0.xyz, biasMultiply); 241 #endif 242 243 half shadowNextCascade = UnitySampleShadowmap_PCF3x3(coord, receiverPlaneDepthBias); 244 shadowNextCascade = lerp(_LightShadowData.r, 1.0f, shadowNextCascade); 245 shadow = lerp(shadow, shadowNextCascade, alpha); 246 } 247 #endif 248 249 return shadow; 250 } 251 ENDCG 252 253 SubShader { 254 Tags{ "ShadowmapFilter" = "HardShadow" } 255 Pass { 256 ZWrite Off ZTest Always Cull Off 257 258 CGPROGRAM 259 #pragma vertex vert 260 #pragma fragment frag_hard 261 #pragma multi_compile_shadowcollector 262 ENDCG 263 } 264 } 265 266 SubShader { 267 Tags{ "ShadowmapFilter" = "HardShadow_FORCE_INV_PROJECTION_IN_PS" } 268 Pass{ 269 ZWrite Off ZTest Always Cull Off 270 271 CGPROGRAM 272 #pragma vertex vert 273 #pragma fragment frag_hard 274 #pragma multi_compile_shadowcollector 275 ENDCG 276 } 277 } 278 279 Subshader { 280 Tags {"ShadowmapFilter" = "PCF_SOFT"} 281 Pass { 282 ZWrite Off ZTest Always Cull Off 283 284 CGPROGRAM 285 #pragma vertex vert 286 #pragma fragment frag_pcfSoft 287 #pragma multi_compile_shadowcollector 288 #pragma target 3.0 289 ENDCG 290 } 291 } 292 293 Subshader{ 294 Tags{ "ShadowmapFilter" = "PCF_SOFT_FORCE_INV_PROJECTION_IN_PS" } 295 Pass{ 296 ZWrite Off ZTest Always Cull Off 297 298 CGPROGRAM 299 #pragma vertex vert 300 #pragma fragment frag_pcfSoft 301 #pragma multi_compile_shadowcollector 302 #pragma target 3.0 303 ENDCG 304 } 305 } 306 307 Fallback Off 308}
投稿2019/09/25 13:19
総合スコア10811
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/26 01:08