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

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

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

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

Unity3D

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

Unity

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

Q&A

解決済

1回答

862閲覧

UnityのSkyboxを自然にしたい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2019/05/12 09:05

##問題
UnityでSkyboxを使おうと思い、画像を自作してSkyboxで使うマテリアルに球状マップでインポートしました。ですが球状にしてしまった為、画像のように集中点のようなものができてしまいました。イメージ説明
例えば、この集中点を真上にするとか、集中点が自然になるように画像を変換するみたいなものは可能なのでしょうか?
何か皆様が工夫されていることでもいいので、教えてください!

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

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

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

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

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

guest

回答1

0

ベストアンサー

簡単にポンと変換するのは難しいかもしれませんね...
直交座標と極座標の相互変換ができるような画像処理ソフトをお持ちでしたら、
手順
のような作業を上下の極についてそれぞれ行ってやればある程度ごまかせるかもしれません。

あるいは、多少処理コストがかかってもかまわなければ、動的に星空を生成する手もあるかと思います。

ShaderLab

1Shader "Skybox/ProceduralStarfield" 2{ 3 Properties 4 { 5 _Seed ("Seed", Float) = 0.0 6 _NebulaColor1 ("Nebula Color 1", Color) = (0, 0, 0.25, 1) 7 _NebulaColor2 ("Nebula Color 2", Color) = (0.25, 0, 0.25, 1) 8 _Rotation ("Rotation Angle", Range(0.0, 360.0)) = 0.0 9 _RotationAxis ("Rotation Axis", Vector) = (1.0, 0.0, 0.0, 0.0) 10 } 11 SubShader 12 { 13 Tags 14 { 15 "RenderType"="Background" 16 "Queue"="Background" 17 "PreviewType"="SkyBox" 18 } 19 20 Pass 21 { 22 ZWrite Off 23 Cull Off 24 25 CGPROGRAM 26 #pragma vertex vert 27 #pragma fragment frag 28 #include "UnityCG.cginc" 29 30 struct appdata 31 { 32 float4 vertex : POSITION; 33 float3 texcoord : TEXCOORD0; 34 }; 35 36 struct v2f 37 { 38 float4 vertex : SV_POSITION; 39 float3 texcoord : TEXCOORD0; 40 }; 41 42 float _Rotation; 43 float3 _RotationAxis; 44 45 v2f vert(appdata v) 46 { 47 v2f o; 48 float cosTheta; 49 float sinTheta; 50 sincos(_Rotation * UNITY_PI / 180.0, sinTheta, cosTheta); 51 float cosThetaI = 1.0 - cosTheta; 52 float3 u = normalize(_RotationAxis); 53 float3 u2 = u * u; 54 float3 us = u * u.yzx; 55 float3x3 r = float3x3( 56 cosTheta + u2.x * cosThetaI, -u.z * sinTheta + us.x * cosThetaI, u.y * sinTheta + us.z * cosThetaI, 57 u.z * sinTheta + us.x * cosThetaI, cosTheta + u2.y * cosThetaI, -u.x * sinTheta + us.y * cosThetaI, 58 -u.y * sinTheta + us.z * cosThetaI, u.x * sinTheta + us.y * cosThetaI, cosTheta + u2.z * cosThetaI 59 ); 60 o.vertex = UnityObjectToClipPos(float4(mul(r, v.vertex.xyz), v.vertex.w)); 61 o.texcoord = v.texcoord; 62 return o; 63 } 64 65 // Ian McEwanによるシンプレックス4Dノイズ 66 // https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 67 inline float4 glslMod(float4 x, float4 y) {return x - y * floor(x / y);} 68 inline float glslMod(float x, float y) {return x - y * floor(x / y);} 69 inline float4 permute(float4 x) {return glslMod(((x * 34.0) + 1.0) * x, 289.0);} 70 inline float permute(float x) {return floor(glslMod(((x * 34.0) + 1.0) * x, 289.0));} 71 inline float4 taylorInvSqrt(float4 r) {return 1.79284291400159 - 0.85373472095314 * r;} 72 inline float taylorInvSqrt(float r) {return 1.79284291400159 - 0.85373472095314 * r;} 73 inline float4 lessThan(float4 x, float4 y) {return saturate(sign(y - x));} 74 75 float4 grad4(float j, float4 ip){ 76 const float4 ones = float4(1.0, 1.0, 1.0, -1.0); 77 float4 p, s; 78 79 p.xyz = floor(frac(j * ip.xyz) * 7.0) * ip.z - 1.0; 80 p.w = 1.5 - dot(abs(p.xyz), ones.xyz); 81 s = lessThan(p, 0.0); 82 p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; 83 84 return p; 85 } 86 87 float snoise(float4 v){ 88 const float2 C = float2( 0.138196601125010504, // (5 - sqrt(5))/20 G4 89 0.309016994374947451); // (sqrt(5) - 1)/4 F4 90 // First corner 91 float4 i = floor(v + dot(v, C.yyyy) ); 92 float4 x0 = v - i + dot(i, C.xxxx); 93 94 // Other corners 95 96 // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) 97 float4 i0; 98 99 float3 isX = step( x0.yzw, x0.xxx ); 100 float3 isYZ = step( x0.zww, x0.yyz ); 101 // i0.x = dot(isX, 1.0); 102 i0.x = isX.x + isX.y + isX.z; 103 i0.yzw = 1.0 - isX; 104 105 // i0.y += dot(isYZ.xy, 1.0); 106 i0.y += isYZ.x + isYZ.y; 107 i0.zw += 1.0 - isYZ.xy; 108 109 i0.z += isYZ.z; 110 i0.w += 1.0 - isYZ.z; 111 112 // i0 now contains the unique values 0,1,2,3 in each channel 113 float4 i3 = clamp(i0, 0.0, 1.0); 114 float4 i2 = clamp(i0 - 1.0, 0.0, 1.0); 115 float4 i1 = clamp(i0 - 2.0, 0.0, 1.0); 116 117 // x0 = x0 - 0.0 + 0.0 * C 118 float4 x1 = x0 - i1 + 1.0 * C.xxxx; 119 float4 x2 = x0 - i2 + 2.0 * C.xxxx; 120 float4 x3 = x0 - i3 + 3.0 * C.xxxx; 121 float4 x4 = x0 - 1.0 + 4.0 * C.xxxx; 122 123 // Permutations 124 i = glslMod(i, 289.0); 125 float j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x); 126 float4 j1 = permute(permute(permute(permute( 127 i.w + float4(i1.w, i2.w, i3.w, 1.0)) 128 + i.z + float4(i1.z, i2.z, i3.z, 1.0)) 129 + i.y + float4(i1.y, i2.y, i3.y, 1.0)) 130 + i.x + float4(i1.x, i2.x, i3.x, 1.0)); 131 // Gradients 132 // ( 7*7*6 points uniformly over a cube, mapped onto a 4-octahedron.) 133 // 7*7*6 = 294, which is close to the ring size 17*17 = 289. 134 135 float4 ip = float4(1.0 / 294.0, 1.0 / 49.0, 1.0 / 7.0, 0.0); 136 137 float4 p0 = grad4(j0, ip); 138 float4 p1 = grad4(j1.x, ip); 139 float4 p2 = grad4(j1.y, ip); 140 float4 p3 = grad4(j1.z, ip); 141 float4 p4 = grad4(j1.w, ip); 142 143 // Normalise gradients 144 float4 norm = taylorInvSqrt(float4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); 145 p0 *= norm.x; 146 p1 *= norm.y; 147 p2 *= norm.z; 148 p3 *= norm.w; 149 p4 *= taylorInvSqrt(dot(p4, p4)); 150 151 // Mix contributions from the five corners 152 float3 m0 = max(0.6 - float3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), 0.0); 153 float2 m1 = max(0.6 - float2(dot(x3, x3), dot(x4, x4)), 0.0); 154 m0 = m0 * m0; 155 m1 = m1 * m1; 156 return 49.0 * (dot(m0 * m0, float3(dot(p0, x0), dot(p1, x1), dot(p2, x2))) 157 + dot(m1 * m1, float2(dot(p3, x3), dot(p4, x4)))); 158 159 } 160 161 float _Seed; 162 float4 _NebulaColor1; 163 float4 _NebulaColor2; 164 165 fixed4 frag(v2f i) : SV_Target 166 { 167 float4 coord = float4(i.texcoord, _Seed); 168 float4 coordN1 = coord + float4(1.2, 3.4, 5.6, 7.8); 169 float4 coordN2 = (coordN1 + float4(2.1, 4.3, 6.5, 8.7)) * 2.0; 170 float4 coordN3 = (coordN2 + float4(5.6, 7.8, 1.2, 3.4)) * 2.0; 171 float4 coordN4 = (coordN3 + float4(6.5, 8.7, 2.1, 4.3)) * 2.0; 172 173 // 恒星...高周波ノイズを冪乗してまばらな点にする 174 float star = pow(snoise(float4(coord.xyz * 32.0, coord.w)) * 0.5 + 0.5, 64.0); 175 176 // 星雲...フラクタルノイズで密度を決め、さらにもう一つノイズを使って色ムラをつける 177 float4 nebula4 = float4(snoise(coordN1), snoise(coordN2), snoise(coordN3), snoise(coordN4)) * 0.5 + 0.5; 178 float nebula = pow(dot(nebula4, float4(1.0, 0.5, 0.25, 0.125)) / 1.875, 2.0); 179 float3 nebulaColor = lerp(_NebulaColor1.rgb, _NebulaColor2.rgb, snoise(coord) * 0.5 + 0.5); 180 181 return fixed4(nebulaColor * nebula + star, 1.0); 182 } 183 ENDCG 184 } 185 } 186}

プロシージャル星空

回転させる例

C#

1using UnityEngine; 2 3public class ProceduralStarfieldRotor : MonoBehaviour 4{ 5 private static readonly int RotationProperty = Shader.PropertyToID("_Rotation"); 6 private static readonly int RotationAxisProperty = Shader.PropertyToID("_RotationAxis"); 7 8 [SerializeField] private float angularSpeed = 15.0f; 9 [SerializeField] private Vector3 axis = Vector3.right; 10 11 private Material skybox; 12 private float angle; 13 14 private void Start() 15 { 16 this.skybox = RenderSettings.skybox; 17 if (this.skybox == null) 18 { 19 Debug.LogError("No Skybox."); 20 this.enabled = false; 21 return; 22 } 23 24 if (!this.skybox.HasProperty(RotationProperty)) 25 { 26 Debug.LogError("Skybox does not have _Rotation."); 27 this.enabled = false; 28 return; 29 } 30 31 if (!this.skybox.HasProperty(RotationAxisProperty)) 32 { 33 Debug.LogError("Skybox does not have _RotationAxis."); 34 this.enabled = false; 35 return; 36 } 37 38 this.skybox.SetVector(RotationAxisProperty, this.axis); 39 } 40 41 private void Update() 42 { 43 this.angle += this.angularSpeed * Time.deltaTime; 44 this.skybox.SetFloat(RotationProperty, this.angle); 45 } 46}

投稿2019/05/12 22:35

編集2019/05/13 21:55
Bongo

総合スコア10807

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

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

退会済みユーザー

退会済みユーザー

2019/05/13 12:35

またまたお世話になります。極座標変換の方はあまりうまくいきませんでした... SkyboxをX軸に回転させる方法ってあるんでしょうか?
Bongo

2019/05/13 21:55

スカイボックスを回転できるかどうかは、スカイボックスのマテリアルが回転に対応しているかによるようですね。マテリアルが回転プロパティを持っていれば、RenderSettings.skyboxでマテリアルを取得してプロパティの値を書き換えることで回せるかと思います。 回答に提示しましたProceduralStarfieldを回転できるよう変更し、スクリプトから回転させる例を追加しました。ご参考になりますでしょうか?
退会済みユーザー

退会済みユーザー

2019/05/14 01:14

なるほど...とても参考になりました!ちなみにこのShaderは全て手書きで作ったのですか?
Bongo

2019/05/14 03:18 編集

一見長くてややこしいように見えますが、コードの大部分を占めているのは4次元ベクトルからノイズ値を得る関数でして、これはコメントにあるように [GLSL Noise Algorithms · GitHub](https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 )で紹介されていたGLSL用コードをShaderLab向けに改造したものです。今回使ったシンプレックスノイズの他にも便利そうなものがいろいろ載っていてお役に立つかと思います。 他には、軸と角度から回転行列を算出する部分は[ロドリゲスの回転公式 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%89%E3%83%AA%E3%82%B2%E3%82%B9%E3%81%AE%E5%9B%9E%E8%BB%A2%E5%85%AC%E5%BC%8F )を採用しました。 それ以外の、frag関数で行っているノイズを加工して星空っぽい見た目にする部分は一応オリジナルではありますが、やっていることはわりとありふれているように思います。独自性を主張できるようなレベルではないんじゃないですかね...? ノイズ関数を除けば大して複雑なものではありませんので、いろいろいじってしまってください。恒星ノイズの周波数を上げ下げすると恒星の細かさが変わりますし、冪乗する指数を上げて星雲のムラを強調することができるでしょう。 他にも、Seedはノイズ計算の第4次元に使われており、ゆっくり変化させると空模様が変わります。今回は星空なのでころころ変化させるものではないでしょうが、星雲でなく空の雲を表現するときには雲に動きがついて面白そうですね。
退会済みユーザー

退会済みユーザー

2019/05/14 04:02

な、なるほど...本当に尊敬します...これから色々見てみます。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問