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

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

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

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

Unity

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

HLSL

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

Q&A

解決済

1回答

1552閲覧

UnityのShaderでSphereの一部にテクスチャを貼り付けたい

hdkkik

総合スコア2

Unity3D

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

Unity

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

HLSL

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

0グッド

0クリップ

投稿2022/04/21 03:12

Unityで360Viewerのようなものを作ろうとしています。
ただし360度全体に画像を貼り付けたいわけではなく、以下のような画像のイメージになります。
用途としては、魚眼カメラを任意の領域に張り付けるためです。

イメージ説明

(参考:https://news.livedoor.com/article/detail/16969597/)

環境は以下になりますが、Unityのバージョン依存等はないと考えております。

Unity: 2021.2
OS: Windows 10
VR: XR Toolkit(Steam VRで利用)

以下が現在実装しているコードになります。Unityのブログを参考にしました。
(コメントアウトしているあたりでなんとかできないのかなと画策しています…)

HLSL

1 2Shader "Custom/360Shader" 3{ 4 Properties 5 { 6 _Tint ("Tint Color", Color) = (.5, .5, .5, .5) 7 [Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0 8 _MarginColor ("Margin Color", Color) = (.5, .3, 0, 0) 9 10 _HorizontalRotation ("Horizontal Rotation", Range(0, 360)) = 0 11 _VerticalRotation ("Vertical Rotation", Range(0, 360)) = 0 12 13 _Horizontal ("Horizontal", Range(0, 360)) = 120 14 _Vertical ("Vertical", Range(0, 180)) = 120 15 16 [NoScaleOffset] _Tex ("Spherical (HDR)", 2D) = "grey" {} 17 } 18 19 SubShader 20 { 21 Tags 22 { 23 "Queue"="Background" 24 "RenderType"="Background" 25 "PreviewType"="Skybox" 26 } 27 28 Cull Off 29 ZWrite Off 30 31 Pass 32 { 33 CGPROGRAM 34 #pragma vertex vert 35 #pragma fragment frag 36 #pragma target 2.0 37 #pragma multi_compile __ _MAPPING_6_FRAMES_LAYOUT 38 #pragma enable_d3d11_debug_symbols 39 40 #include "UnityCG.cginc" 41 42 sampler2D _Tex; 43 half4 _Tex_HDR; 44 half4 _Tint; 45 half4 _MarginColor; 46 half _Exposure; 47 float _HorizontalRotation; 48 float _VerticalRotation; 49 float _Horizontal; 50 float _Vertical; 51 52 inline float2 ToRadialCoords(float3 coords) 53 { 54 float3 normalizedCoords = normalize(coords); 55 float latitude = acos(normalizedCoords.y); 56 float longitude = atan2(normalizedCoords.z, normalizedCoords.x); 57 float2 sphereCoords = float2(longitude, latitude) * float2(0.5 / UNITY_PI, 1.0 / UNITY_PI); 58 return float2(0.5, 1.0) - sphereCoords; 59 } 60 61 float3 RotateAroundCenter(float3 vertex, float xDegrees, float yDegrees) 62 { 63 float x = xDegrees * UNITY_PI / 360.0; 64 float y = yDegrees * UNITY_PI / 360.0; 65 66 float sinX, cosX, sinY, cosY; 67 68 sincos(x, sinX, cosX); 69 sincos(y, sinY, cosY); 70 71 float2x2 matrixX = float2x2(cosX, -sinX, sinX, cosX); 72 float2x2 matrixY = float2x2(cosY, -sinY, sinY, cosY); 73 float2 mulx = mul(matrixX, vertex.yz); 74 float2 muly = mul(matrixY, vertex.xz); 75 // return mul((vertex.x, mulx.x, mulx.y), float3(muly, vertex.y)); 76 // return float3(vertex.x, mulx.x, mulx.y).xzy; 77 return float3(muly, vertex.y).xzy; 78 } 79 80 81 82 struct appdata 83 { 84 float4 vertex : POSITION; 85 UNITY_VERTEX_INPUT_INSTANCE_ID 86 }; 87 88 struct v2f 89 { 90 float4 vertex : SV_POSITION; 91 float3 texcoord : TEXCOORD0; 92 float4 layout3DScaleAndOffset : TEXCOORD3; 93 UNITY_VERTEX_OUTPUT_STEREO 94 }; 95 96 v2f vert(appdata v) 97 { 98 v2f o; 99 UNITY_SETUP_INSTANCE_ID(v); 100 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); 101 102 float3 rotated = RotateAroundCenter(v.vertex, _VerticalRotation, _HorizontalRotation); 103 104 o.vertex = UnityObjectToClipPos(rotated); 105 o.texcoord = v.vertex.xyz; 106 107 return o; 108 } 109 110 fixed4 frag(v2f i) : SV_Target 111 { 112 float2 tc = ToRadialCoords(i.texcoord); 113 114 // Cut around the vertical angles with center at 90 degrees 115 if (_Vertical/360 < tc.y) 116 return _MarginColor; 117 tc.y = fmod(tc.y * 360/_Vertical, 1); 118 119 // Cut around the horizontal angles 120 if (tc.x > _Horizontal/360) 121 return _MarginColor; 122 tc.x = fmod(tc.x * 360/_Horizontal, 1); 123 124 half4 tex = tex2D(_Tex, tc); 125 half3 c = DecodeHDR(tex, _Tex_HDR); 126 c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb; 127 c *= _Exposure; 128 return half4(c, 1); 129 } 130 ENDCG 131 } 132 } 133 134 Fallback Off 135} 136

実行結果は以下のような感じになり、垂直方向が意図した結果になっていません。
Shaderを始めたばかりで、知見のある方の意見を頂戴したく、、、
イメージ説明
イメージ説明
(サンプル画像)

よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

もっとシンプルに考えていいんじゃないかと思い、ご提示いただいたコードを下記のようにごっそり変更してしまいました。
特定の緯度・経度の範囲を示す球面上の四角形に合わせてテクスチャを貼り付ける...と解釈して考えてみましたが、もしかすると意図を取り違えているかもしれませんので、あのような形だと不都合な点がありましたらコメントいただければ私の分かる範囲でしたら修正を加えてみようと思います。

ShaderLab

1Shader "Custom/360Shader" 2{ 3 Properties 4 { 5 _Tint ("Tint Color", Color) = (.5, .5, .5, .5) 6 [Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0 7 _MarginColor ("Margin Color", Color) = (.5, .3, 0, 0) 8 9 // テクスチャを貼り付ける球面上の四角形を定義する左、右、下、上の 10 // 4つの角度を表すプロパティを用意する 11 _LeftLongitude ("Left Longitude", Range(-180, 180)) = 0 12 _RightLongitude ("Right Longitude", Range(-180, 180)) = 0 13 _BottomLatitude ("Bottom Latitude", Range(-90, 90)) = 0 14 _TopLatitude ("Top Latitude", Range(-90, 90)) = 0 15 16 [NoScaleOffset] _Tex ("Spherical (HDR)", 2D) = "grey" {} 17 } 18 19 SubShader 20 { 21 Tags 22 { 23 "Queue"="Background" 24 "RenderType"="Background" 25 "PreviewType"="Skybox" 26 } 27 28 Cull Front 29 ZWrite Off 30 31 Pass 32 { 33 CGPROGRAM 34 #pragma vertex vert 35 #pragma fragment frag 36 #pragma target 2.0 37 38 #include "UnityCG.cginc" 39 40 sampler2D _Tex; 41 half4 _Tex_HDR; 42 half4 _Tint; 43 half4 _MarginColor; 44 half _Exposure; 45 46 // 4つの角度を受け取るユニフォーム変数を用意する 47 float _LeftLongitude; 48 float _RightLongitude; 49 float _BottomLatitude; 50 float _TopLatitude; 51 52 struct appdata 53 { 54 float4 vertex : POSITION; 55 UNITY_VERTEX_INPUT_INSTANCE_ID 56 }; 57 58 struct v2f 59 { 60 float4 vertex : SV_POSITION; 61 float3 texcoord : TEXCOORD0; 62 UNITY_VERTEX_OUTPUT_STEREO 63 }; 64 65 v2f vert(appdata v) 66 { 67 v2f o; 68 UNITY_SETUP_INSTANCE_ID(v); 69 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); 70 o.vertex = UnityObjectToClipPos(v.vertex); 71 o.texcoord = v.vertex.xyz; 72 return o; 73 } 74 75 inline float inverseLerp(float a, float b, float value) 76 { 77 return a != b ? (value - a) / (b - a) : 0.0; 78 } 79 80 half4 frag(v2f i) : SV_Target 81 { 82 // 左端を起点とした相対的な右端の角度を求める 83 float rightLongitude = _RightLongitude - _LeftLongitude; 84 while (rightLongitude < 0.0) 85 { 86 rightLongitude += 360.0; 87 } 88 89 // ピクセルの方角を正規化しておき... 90 i.texcoord = normalize(i.texcoord); 91 92 // 左端の方角を基準とするようY軸周りに回転させる 93 float2 origin = 0.0; 94 sincos(radians(_LeftLongitude), origin.y, origin.x); 95 i.texcoord.zx = mul(float2x2(origin, -origin.y, origin.x), i.texcoord.zx); 96 97 // Uについては左端~右端を0.0~1.0に対応づけ、Vについては下端~上端を0.0~1.0に対応づける 98 float2 tc = float2( 99 inverseLerp(0.0, rightLongitude, degrees(atan2(i.texcoord.x, i.texcoord.z)) + 180.0), 100 inverseLerp(_BottomLatitude, _TopLatitude, degrees(asin(i.texcoord.y)))); 101 102 // 0.0~1.0の範囲を外れた領域は_MarginColorで塗り... 103 if (any(abs(tc - saturate(tc)) > 0.0)) 104 { 105 return _MarginColor; 106 } 107 108 // 範囲内の領域はテクスチャをサンプリングして塗る 109 half4 tex = tex2D(_Tex, tc); 110 half3 c = DecodeHDR(tex, _Tex_HDR); 111 c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb; 112 c *= _Exposure; 113 return half4(c, 1); 114 } 115 ENDCG 116 } 117 } 118 Fallback Off 119}

図

投稿2022/04/21 12:54

Bongo

総合スコア10807

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

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

hdkkik

2022/04/21 14:00

ありがとうございます。おっしゃる通りですね… はじめはおっしゃるようなシンプルな構成を考えていたんですが、向きを変更できないのでよくないと考えて質問させていただいたような方向性にしました。 一点あるとすれば _VerticalLongitude ("Left Longitude", Range(0, 180)) = 0 _HorizontalLongitude ("Right Longitude", Range(0, 180)) = 0 _BottomLatitude = _VerticalLongitude / 2 _BottomLatitude = _TopLatitude _LeftLongitude = _HorizontalLongitude / 2 _LeftLongitude = _RightLongitude といったとこでしょうか 解答ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問