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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Unity

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

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

Q&A

解決済

1回答

2817閲覧

Unity テクスチャ 謎の線

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

0グッド

0クリップ

投稿2020/08/04 04:49

編集2020/08/04 12:39

前提・実現したいこと

テクスチャに生じる謎の線を直したい

該当のソースコード

ShaderLab

1Shader "Unlit/StandardTexture" 2{ 3 Properties 4 { 5 _MainTex ("Texture", 2D) = "white" {} 6 _Color ("Color", Color) = (1,1,1,1) 7 } 8 SubShader 9 { 10 Tags { "RenderType"="Opaque" "Queue"="Transparent+2000"} 11 ZWrite Off 12 ZTest Always 13 Blend SrcAlpha OneMinusSrcAlpha 14 15 Pass 16 { 17 Stencil 18 { 19 Ref 2 20 Comp Equal 21 } 22 23 CGPROGRAM 24 #pragma vertex vert 25 #pragma fragment frag 26 // make fog work 27 #pragma multi_compile_fog 28 29 #include "UnityCG.cginc" 30 31 struct appdata 32 { 33 float4 vertex : POSITION; 34 float2 uv : TEXCOORD0; 35 }; 36 37 struct v2f 38 { 39 float2 uv : TEXCOORD0; 40 UNITY_FOG_COORDS(1) 41 float4 vertex : SV_POSITION; 42 }; 43 44 sampler2D _MainTex; 45 float4 _MainTex_ST; 46 fixed4 _Color; 47 48 v2f vert (appdata v) 49 { 50 v2f o; 51 o.vertex = UnityObjectToClipPos(v.vertex); 52 o.uv = TRANSFORM_TEX(v.uv, _MainTex); 53 UNITY_TRANSFER_FOG(o,o.vertex); 54 return o; 55 } 56 57 fixed4 frag (v2f i) : SV_Target 58 { 59 float2 uv = frac(i.uv); 60 61 float2 duvdx = ddx(i.uv); 62 float2 duvdy = ddx(i.uv); 63 64 fixed4 col = tex2Dgrad(_MainTex,uv,duvdx,duvdy) * _Color; 65 66 return col; 67 } 68 ENDCG 69 } 70 } 71} 72

試したこと

Graphics.Drawmeshで描画しているのですが、謎の黒い線のようなものが、テクスチャに生じてしまいます。

tex2Dgradを使っていますが、変わりません。

Generate Mip Mapsはオン、Wrap ModeはClamp、Filter ModeはTrilinearです。

恐らく、メッシュ同士が隣り合っていて、タイルの色が漏れてしまっているのが、最大の原因だと思うのですが、どうシェーダーを書けば直せるのか、分からなかったため、質問しました。

以下の画像のようになっています。↓

イメージ説明

【追記】

CameraのorthographicSizeを変更したときに、謎の線やちらつきが生じるようです。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using System.Diagnostics; 5using System; 6 7public class CameraScript : MonoBehaviour 8{ 9 private Camera m_cam; 10 private float zoomSpeed = 10f * 3; 11 private float scrollSpeed = 20f * 5; 12 private float dragSpeed = 0.5f; 13 public Vector2 zoom = new Vector2(3f, 100f); 14 [HideInInspector] 15 public float targetZoom; 16 private bool wait = true; 17 public int size; 18 [NonSerialized] 19 public bool editor = true; 20 public Camera cam 21 { 22 get 23 { 24 if (this.m_cam == null) 25 { 26 this.m_cam = base.GetComponent<Camera>(); 27 } 28 return this.m_cam; 29 } 30 } 31 public float currentZoom 32 { 33 get 34 { 35 return this.cam.orthographicSize; 36 } 37 set 38 { 39 if (this.cam.orthographicSize == value) 40 { 41 return; 42 } 43 this.cam.orthographicSize = value; 44 } 45 } 46 private void Start() 47 { 48 Application.targetFrameRate = 60; 49 this.currentZoom = 300; 50 this.targetZoom = size; 51 base.transform.position = new Vector3(base.transform.position.x, base.transform.position.y, 52 -this.currentZoom); 53 base.StartCoroutine("Starter"); 54 } 55 [DebuggerHidden] 56 private IEnumerator Starter() 57 { 58 this.zoomSpeed /= 2f; 59 yield return new WaitForSeconds(1f); 60 this.targetZoom = size; 61 /*while(this.currentZoom > 33f) 62 { 63 yield return new WaitForSeconds(0.333f); 64 }*/ 65 this.zoomSpeed *= 2f; 66 this.wait = false; 67 } 68 private void Update() 69 { 70 if (!this.wait) 71 { 72 this.MovementKeyboardGame(); 73 this.MovementMouseGame(); 74 this.ZoomMouse(); 75 } 76 77 if (editor) 78 { 79 float xPos = Mathf.Clamp(transform.position.x, 0, 200); 80 float yPos = Mathf.Clamp(transform.position.y, 0, 200); 81 82 transform.position = new Vector3(xPos, yPos, -currentZoom); 83 } 84 } 85 private void FixedUpdate() 86 { 87 this.GoToTargetZoom(); 88 } 89 private void MovementMouseGame() 90 { 91 if (Input.GetMouseButton(2)) 92 { 93 base.transform.Translate(-new Vector3(Input.GetAxis("Mouse X") * this.dragSpeed * Time.deltaTime * 100f, Input.GetAxis("Mouse Y") * this.dragSpeed * Time.deltaTime * 100f, 0f)); 94 } 95 } 96 97 private void MovementKeyboardGame() 98 { 99 base.transform.Translate(new Vector3(Input.GetAxis("Horizontal") * this.scrollSpeed * Time.deltaTime, Input.GetAxis("Vertical") * this.scrollSpeed * Time.deltaTime, 0f)); 100 } 101 102 private void ZoomMouse() 103 { 104 if (Input.GetAxis("Mouse ScrollWheel") != 0f) 105 { 106 this.targetZoom -= Input.GetAxis("Mouse ScrollWheel") * this.zoomSpeed; 107 this.targetZoom = Mathf.Clamp(this.targetZoom, this.zoom.x, this.zoom.y); 108 } 109 } 110 111 private void GoToTargetZoom() 112 { 113 if (this.currentZoom != this.targetZoom) 114 { 115 float num = Mathf.Clamp(Mathf.Abs(this.currentZoom - this.targetZoom), 0.3f, 0.5f); 116 float t = Time.deltaTime * this.zoomSpeed * num; 117 float num2 = Mathf.Lerp(this.currentZoom, this.targetZoom, t); 118 if (Mathf.Abs(num2 - this.targetZoom) < 0.01f) 119 { 120 this.currentZoom = this.targetZoom; 121 } 122 else 123 { 124 this.currentZoom = num2; 125 } 126 if (this.currentZoom >= 5f && this.currentZoom != -base.transform.position.z) 127 { 128 base.transform.Translate(new Vector3(0f, 0f, -(this.currentZoom + base.transform.position.z))); 129 } 130 } 131 } 132}

【色漏れが起こっているテクスチャの画像】

イメージ説明
![イメージ説明

【再追記】

エディター上では、色漏れが見えないのですが、ビルドして、ゲームを配布形式にすると、謎の線が生じる現象が起きます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

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

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

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

Bongo

2020/08/04 12:13

おそらくおっしゃるように色漏れが起こっているような気がしますね... 以前「Unity orthographicSize ちらつき」(https://teratail.com/questions/227861 )の追記部分で申し上げた、UV座標を少しだけ縮めてテクスチャの外周をそぎ落とすような措置が必要かもしれません。 念のため、その色漏れが起こっているテクスチャの画像をご提示いただけますでしょうか?
退会済みユーザー

退会済みユーザー

2020/08/04 12:27

質問内容を修正致しました。
guest

回答1

0

ベストアンサー

ご提示いただいた壁テクスチャや、画面左のあずき色の岩にかすかに生じている黒線の出かたから察しますに、今回は1タイルごとに1テクスチャという方式でしょうかね?
もしそうであり、かつテクスチャの「Wrap Mode」が現状「Repeat」ならば、それを「Clamp」にすると反対側のエッジの色が漏れることはなくなるだろうと思います。

図

テクスチャの設定を変えたくない場合は、追記依頼欄で申し上げた外周の削ぎ落としを加えてやるのがいいんじゃないでしょうかね?

ShaderLab

1Shader "Unlit/StandardTexture" 2{ 3 Properties 4 { 5 _MainTex ("Texture", 2D) = "white" {} 6 _Color ("Color", Color) = (1,1,1,1) 7 } 8 SubShader 9 { 10 Tags { "RenderType"="Opaque" "Queue"="Transparent+2000"} 11 ZWrite Off 12 ZTest Always 13 Blend SrcAlpha OneMinusSrcAlpha 14 15 Pass 16 { 17 Stencil 18 { 19 Ref 2 20 Comp Equal 21 } 22 23 CGPROGRAM 24 #pragma vertex vert 25 #pragma fragment frag 26 // make fog work 27 #pragma multi_compile_fog 28 29 #include "UnityCG.cginc" 30 31 struct appdata 32 { 33 float4 vertex : POSITION; 34 float2 uv : TEXCOORD0; 35 }; 36 37 struct v2f 38 { 39 float2 uv : TEXCOORD0; 40 UNITY_FOG_COORDS(1) 41 float4 vertex : SV_POSITION; 42 }; 43 44 sampler2D _MainTex; 45 float4 _MainTex_ST; 46 fixed4 _Color; 47 48 v2f vert (appdata v) 49 { 50 v2f o; 51 o.vertex = UnityObjectToClipPos(v.vertex); 52 o.uv = TRANSFORM_TEX(v.uv, _MainTex); 53 UNITY_TRANSFER_FOG(o,o.vertex); 54 return o; 55 } 56 57 fixed4 frag (v2f i) : SV_Target 58 { 59 float2 uv = saturate(i.uv); 60 61 // 縦横の変化率をddxとddyで個別に求めてもいいですが、「縦横の変化率の絶対値の和」だけが 62 // 必要な場合であれば、fwidthを使用してもいいでしょう 63 float2 cornerOffset = fwidth(i.uv); 64 uv = lerp(cornerOffset, 1.0 - cornerOffset, uv); 65 66 // 今回の場合は一般的なUV座標を使っていますので、tex2Dgradでなくとも大丈夫だろうと思います 67 fixed4 col = tex2D(_MainTex, uv) * _Color; 68 69 return col; 70 } 71 ENDCG 72 } 73 } 74}

ですがWrap Mode設定で対応可能でしたら、そちらの方が削ぎ落としがないので元のテクスチャに忠実な見た目になるかと思います。

※テクスチャの「Tiling」や「Offset」はいじっているでしょうかね?これらの設定はデフォルトのままで描画することを想定したのですが、もしこれらを変更する必要がある場合はもう少し手を加える必要があるでしょう。

投稿2020/08/04 21:43

Bongo

総合スコア10811

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

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

退会済みユーザー

退会済みユーザー

2020/08/05 01:01

いつも回答していただき、ありがとうございます。 質問なのですが、 float2 uv = saturate(i.uv); saturateはなにをしているものなのでしょうか? 調べると「指定された値を0〜1の範囲でクランプします」と出てくるのですが…いまいち、なにを意味しているのかが分かりませんでした。
Bongo

2020/08/05 03:08

おっしゃる通り、saturateは値が1を上回るなら1に、0を下回るなら0に制限する作用となります。一方、ご質問者さんがご提示いただいたコードで使われているfracは値の小数部分を抜き出す作用となり、当初シェーダー案を検討し始めたときに「fracだとUV座標が1を越えると0に戻るだろうから反対側の色が出てきてしまいそう...」などと考えてsaturateに変更したのがそのまま残ってしまったものです。ですが、今回の場合ですと1タイル1テクスチャの方式ですので、そもそもUV座標は最初から0~1の範囲におさまっており、fracでもsaturateでも、あるいは何も関数を通さずにそのままUV座標を使ったとしても大丈夫そうでしたね。
退会済みユーザー

退会済みユーザー

2020/08/05 04:36

分かりました。回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問