質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

3回答

6148閲覧

Unityで、rotationの傾きを維持したままObjectの向きを変えたい

kaghita

総合スコア8

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/09/15 11:49

編集2019/09/19 07:16

実現したいもの

今こんなものが出来ているのですが、(画像1)
イメージ説明
コードはこう

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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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を変えたりすると、ひずみがリセットされてしまいます。また、プレイモード中にTilterAngleを変えてもひずみ量は変わりません。さらに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

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaghita

2019/09/26 01:08

両方試しました。どちらも問題なく、どこまで行ってもちゃんと影が現れました。何度もお世話をかけてしまいました。ありがとうございます!
guest

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}

「上下に動く時は遅くなってしまう」について
ThirdPersonCharacterMoveメソッドをご覧いただきますと、入力された移動ベクトルをキャラクターローカルの向きに変換して使用していることがお分かりいただけるかと思います。キャラクターが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点を調整してみたところ、下図のような動きになりました。だいぶキビキビしたように思いますが、いかがでしょうか?

図1

「上下に動く時は遅くなってしまう」について追記
すいません、前後方向の速さ調整が不十分で、水平方向よりも遅くなっていました。付け焼き刃ですが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}

プロジェクト設定で上記シェーダーをスクリーンスペースシャドウ生成時に使用するよう設定したところ...

図2

下図のような動きになりました。オブジェクトを剪断変形するかのようにひずめるため、45°回転方式とは違ってオブジェクトの上面が見えやすいという特徴があり、なんとなく縦に引き延ばされたように感じます。Z方向にわずかに縮めてやるとバランスがよくなるかもしれません。

図3

投稿2019/09/22 20:25

編集2019/09/23 04:20
Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaghita

2019/09/23 10:04

すみません。 ”Move2スクリプトでStart時点のキャラクターの回転を覚えておき、Move実行の際に渡すm_Moveを初期回転分だけ回してやってはいかがでしょう。” の部分をもっと詳しくお願いします。 回転を覚えておくというのは、transform.rotationを変数に代入しておくという意味でいいんですよね? m_Moveを初期回転分だけ回すには、その変数をどこかに入れればいいということなんでしょうか? だとしたらどこに入れればいいんでしょうか? Move関数には回転を入れられる引数が無いから多分ここでは無いですよね?
Bongo

2019/09/23 15:30

はい、「回転を覚えておく」と申し上げたのはm_InitialRotationにtransform.rotationを代入しておくことのつもりでした。そしてm_Moveを回すのは「m_Character.Move(m_InitialRotation * m_Move, crouch, m_Jump);」という具合にMove実行時に行っております。m_Moveをそのまま引数に渡す代わりに、m_Moveをm_InitialRotationで回転した結果を渡すようにしてみました。 ただし、その後の追記で申し上げたように、このやり方だと上下移動の速さがまだ足りなかったですね。45°に傾けていることによる錯覚のせいか案外いい感じに見えてしまい、気付くのが遅れてしまいました...
kaghita

2019/09/24 02:35

おまけのForFunkyProjectionの方法を試してみたんですが、こちらの方がThirdPersonCharacterを使う必要がなく、理想的に動かせると判断しました。こっちだと球体のオブジェクトなどの表現に工夫が要りそうですが、この方法をベースに進めていこうと思います。丁寧なご教授ありがとうございました。
kaghita

2019/09/25 07:48

すみません! Resourceフォルダを作ってそこにForFunkyProjectionのファイルを入れてproject設定でこれを使うようにしたんですが、 undeclared identifier 'computeCameraSpacePosFromDepthAndInvProjMat' Compiling Vertex program とエラーが出てGameviewに影が出ないんです。 computeCameraSpacePosFromDepthAndInvProjMatが定義されてないということなんでしょうか?
Bongo

2019/09/25 13:20

関数が見つからないようですね... 改造元にしたのは2019.2.6f1版ビルトインシェーダー(https://netstorage.unity3d.com/unity/fe82a0e88406/builtin_shaders-2019.2.6f1.zip )に入っているDefaultResourcesExtra/Internal-ScreenSpaceShadows.shaderだったのですが、ファイルは合っていたでしょうか?あるいはバージョン違いとかもあるんでしょうかね? 念のため改造版のInternal-ScreenSpaceShadowsForFunkyProjection.shaderを省略なしで追記いたします。文字数が多いため別回答になってしまいますがご容赦ください。元のファイルにはけっこう詳細にコメントが入れられていましたが、それらを大幅に削除したところ1回答分におさめることができました。こちらでもうまくいかないでしょうか?
kaghita

2019/09/25 15:14

エラーは無事解消しました。ありがとうございます。 ただ、今度は移動した場所によって、影が消えたり濃度が変わったりしてしまいます。 どうやらGameviewで正投影法(orthographic)を使っていることが関係しているようなのですが、CameraやLightの位置を色々変えたりしても今一つ法則性が見えてきません。出来ればorthographicを使いたいんです。 因みにThirdPersonCharacterは使わず、試したこと2のMove2Scriptで動かしています。
Bongo

2019/09/25 16:40

なるほど...Orthographicでは試しておらず気付きませんでしたが、傾きを大きくすると影が消えますね... どうやらPerspectiveでもClipping PlanesのFarを小さくしたりすると影が消え始めるようです。何だかライトから見たときのデプスをレンダリングする際に可視領域を正しく求められず、影描画の必要なしと判定されているような動きに感じました。 ちょっと試した感じですと、ビュー行列ではなくプロジェクション行列の方をいじればライトのデプスレンダリングに悪影響を与えずに済みそうでした。字数を使い切ってしまったためまたもや別回答に分かれてしまいましたが、Tilterに変更を加えてみましたので追記します。これだとどうでしょうか?
guest

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

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問