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

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

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

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

Unity

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

Q&A

解決済

3回答

1427閲覧

サウンドと連携させてポストエフェクトを動かす方法がわからない

OZ-

総合スコア6

C#

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

Unity

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

0グッド

0クリップ

投稿2020/07/19 03:35

編集2020/07/19 04:26

サウンドと連携させてポストエフェクトを動かしたいです。

下記サイトを参考にスクリプト(コードB)とシェーダー(コードC)を作成し、メインカメラに貼り付けました。

外部サイト:Unity サウンドと同期してぷるぷるするエフェクト

画像のバーを弄ることでエフェクトが付くようにはなったのですが、
サウンドに連動した動きにはなりません。

参照サイトでは下記コード(コードA)でサウンドから情報を取り出し、連動してエフェクトを動かせると書いてあります。
恐らくコードAをコードBもしくはコードCのどこかに追記するということだと理解しています。
(この前提から間違っているかもしれません)
色々試してみたのですが、既存のコードにどう入れても何かしらのエラーが出てしまいます。

どのようにすれば、サウンドと連動させてコードBないしコードCのエフェクトを動かせるのか教えてください。

コードA

C#

1// スペクトラムを取得 2var spectrum = audioSource.GetSpectrumData(resolution, 0, FFTWindow.BlackmanHarris); 3var deltaFreq = AudioSettings.outputSampleRate / resolution; 4 5// スペクトラムから取り出した値を格納する変数 6float low = 0f; 7float mid = 0f; 8float high = 0f; 9 10// 周波数帯に応じて値を取り出す 11for (var i = 0; i < resolution; ++i) { 12 var freq = deltaFreq * i; 13 if (freq <= lowFreqThreshold) low += spectrum[i]; 14 else if (freq <= midFreqThreshold) mid += spectrum[i]; 15 else if (freq <= highFreqThreshold) high += spectrum[i]; 16} 17 18// 値を調整 19low *= lowEnhance; 20mid *= midEnhance; 21high *= highEnhance; 22low *= .15f; 23mid *= .15f; 24high *= .15f; 25 26// ポストエフェクト側の変数に値を渡す 27imageEffest.powerA = high; 28imageEffest.powerB = mid; 29imageEffest.powerC = low;

コードB

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class ColorOfset : MonoBehaviour { 6 7 private Material _material; 8 protected string _shaderName = "ImageEffect/ColorOfset"; 9 10 [SerializeField] 11 [Range(1, 1000)] 12 public float speed; 13 [SerializeField] 14 [Range(0, 1)] 15 public float powerA; 16 [SerializeField] 17 [Range(0, 1)] 18 public float powerB; 19 [SerializeField] 20 [Range(0, 1)] 21 public float powerC; 22 23 24 protected virtual void Awake() 25 { 26 Shader shader = Shader.Find(_shaderName); 27 _material = new Material(shader); 28 } 29 30 void OnRenderImage(RenderTexture source, RenderTexture destination) 31 { 32 UpdateMaterial(); 33 34 Graphics.Blit(source, destination, _material); 35 } 36 37 void UpdateMaterial() 38 { 39 _material.SetFloat("_Speed", speed); 40 _material.SetFloat("_PowerA", powerA); 41 _material.SetFloat("_PowerB", powerB); 42 _material.SetFloat("_PowerC", powerC); 43 } 44}

コードc

c#

1Shader "ImageEffect/ColorOfset" 2{ 3 Properties 4 { 5 _MainTex ("Texture", 2D) = "white" {} 6 _Speed ("Speed", Range(1, 1000)) = 500 7 _PowerA ("PowerA", Range(0, 1)) = 0 8 _PowerB ("PowerB", Range(0, 1)) = 0 9 _PowerC ("PowerC", Range(0, 1)) = 0 10 } 11 SubShader 12 { 13 // No culling or depth 14 Cull Off ZWrite Off ZTest Always 15 16 Pass 17 { 18 CGPROGRAM 19 #pragma vertex vert 20 #pragma fragment frag 21 22 #include "UnityCG.cginc" 23 24 25 struct appdata 26 { 27 float4 vertex : POSITION; 28 float2 uv : TEXCOORD0; 29 }; 30 31 struct v2f 32 { 33 float2 uv : TEXCOORD0; 34 float4 vertex : SV_POSITION; 35 }; 36 37 v2f vert (appdata v) 38 { 39 v2f o; 40 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 41 o.uv = v.uv; 42 return o; 43 } 44 45 46 // 47 float rand(float2 co) { 48 return frac(sin(dot(co.xy, float2(12.9898, 78.233))) * 43758.5453); 49 } 50 51 // 52 sampler2D _MainTex; 53 float _Speed; 54 float _PowerA; 55 float _PowerB; 56 float _PowerC; 57 58 fixed4 frag (v2f i) : SV_Target 59 { 60 fixed4 tex = tex2D(_MainTex, i.uv); 61 62 float3 col; 63 float time = _Time * _Speed; 64 65 float ran = rand(float2(1, 10)); 66 67 col.r = tex2D(_MainTex, i.uv).r; 68 col.g = tex2D(_MainTex, i.uv - float2(cos(time) * .05 * _PowerA * rand(float2(-50, 50)), sin(time) * .035) * _PowerC * rand(float2(-25, 25))).g; 69 col.b = tex2D(_MainTex, i.uv - float2(sin(time) * .06 * _PowerB * rand(float2(-50, 50)), cos(time) * .025) * _PowerC * rand(float2(-25, 25))).b; 70 71 return float4(col, 1); 72 } 73 ENDCG 74 } 75 } 76}

インスペクタ

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

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

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

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

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

bboydaisuke

2020/07/19 03:47

> 何かしらのエラー 何というエラーがどの行で出ますか? エラーは Console のログをコピペして正確に教えてください。 どの行、というのは貼り付けてあるコードの内、どの行に対してのエラーが出ているのかを正確に示してください。
OZ-

2020/07/19 04:29

誤解を招く表現になっていたので本文を修正しました。 そして、「具体的にどのようなエラーが出たから解決したい」ではなく、 「コードAをどのようにコードBないし、コードCに組み込めば「サウンドに連動した動き」になるのかを伺いたい」という質問になります。 >>参照サイトでは下記コード(コードA)でサウンドから情報を取り出し、連動してエフェクトを動かせると書いてあります。 >>恐らくコードAをコードBもしくはコードCのどこかに追記するということだと理解しています。 >>(この前提から間違っているかもしれません) >>色々試してみたのですが、既存のコードにどう入れても何かしらのエラーが出てしまいます。
guest

回答3

0

恐らくコードAをコードBもしくはコードCのどこかに追記するということだと理解しています。
(この前提から間違っているかもしれません)

そうですね。そこが間違っています。
コード C は HLSL で書かれた(C# ではありません)シェーダーです。まずこれでシェーダーを作ります。

コード B は C# で書かれていて、適当な GameObject にアタッチして使います。現在使っている GameObject にアタッチせず、ゲーム管理用にずっといる GameObject か、もしくは新規に作った Empty Object にアタッチするでしょう。このスクリプトコンポーネントはコード C で作った Shader のパラメーターを動かします。結果としてコード C のシェーダーを使って描画したオブジェクトの見た目が変わります。

コード A は、コード B の機能を呼び出すためにブログの作者が書いたコードですが、これは不完全なものでコピペしても動きません。例えば imageEffest という変数は ColorOfset コンポーネントのインスタンスと推測できますが、変数の宣言や値をどうやって取得したのかなどの情報が欠落した「動かないコード」です。なのでこれを使いたければ、そのブログの欠落した情報をひとつひとつ調べて補完する必要があります。

投稿2020/07/19 07:13

編集2020/07/19 07:39
bboydaisuke

総合スコア5270

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

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

OZ-

2020/07/19 14:35

ありがとうございます! ~オブジェクトの見た目が変わります。は理解しており、そのため添付画像のような画面が出力されています。 「動かないコード」であることも理解しており、自分のいまの技量では欠落した情報を補完しきるのは難しいようです。 なので、どのようにすれば動かせるのか?という質問でした。
bboydaisuke

2020/07/19 14:42 編集

すみませんが、動かないコードがどうすれば動くかを一つ一つ調べて動くようになおすのは私や他の人にとっても大変時間や手間がかかることなので、まずはご自分でチャレンジして、わからないところを質問してください。
guest

0

コードAをコードBに下記のように組み込むと動く。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5[RequireComponent(typeof(AudioSource))] 6public class ColorOfset : MonoBehaviour 7{ 8 9 private Material _material; 10 protected string _shaderName = "ImageEffect/ColorOfset"; 11 12 private AudioSource audioSource; 13 public int resolution = 1024; 14 public Transform lowMeter, midMeter, highMeter; 15 public float lowFreqThreshold = 14700, midFreqThreshold = 29400, highFreqThreshold = 44100; 16 public float lowEnhance = 1f, midEnhance = 10f, highEnhance = 100f; 17 18 19 [SerializeField] 20 [Range(1, 1000)] 21 public float speed; 22 [SerializeField] 23 [Range(0, 1)] 24 public float powerA; 25 [SerializeField] 26 [Range(0, 1)] 27 public float powerB; 28 [SerializeField] 29 [Range(0, 1)] 30 public float powerC; 31 32 protected virtual void Awake() 33 { 34 Shader shader = Shader.Find(_shaderName); 35 _material = new Material(shader); 36 37 audioSource = GetComponent<AudioSource>(); 38 } 39 40 void OnRenderImage(RenderTexture source, RenderTexture destination) 41 { 42 UpdateMaterial(); 43 44 Graphics.Blit(source, destination, _material); 45 } 46 47 void UpdateMaterial() 48 { 49 // スペクトラムを取得 50 var spectrum = audioSource.GetSpectrumData(resolution, 0, FFTWindow.BlackmanHarris); 51 var deltaFreq = AudioSettings.outputSampleRate / resolution; 52 53 // スペクトラムから取り出した値を格納する変数 54 float low = 0f; 55 float mid = 0f; 56 float high = 0f; 57 58 // 周波数帯に応じて値を取り出す 59 for (var i = 0; i < resolution; ++i) 60 { 61 var freq = deltaFreq * i; 62 if (freq <= lowFreqThreshold) low += spectrum[i]; 63 else if (freq <= midFreqThreshold) mid += spectrum[i]; 64 else if (freq <= highFreqThreshold) high += spectrum[i]; 65 } 66 67 // 値を調整 68 low *= lowEnhance; 69 mid *= midEnhance; 70 high *= highEnhance; 71 low *= .15f; 72 mid *= .15f; 73 high *= .15f; 74 75 // ポストエフェクト側の変数に値を渡す 76 powerA = high; 77 powerB = mid; 78 powerC = low; 79 80 81 _material.SetFloat("_Speed", speed); 82 _material.SetFloat("_PowerA", powerA); 83 _material.SetFloat("_PowerB", powerB); 84 _material.SetFloat("_PowerC", powerC); 85 86 } 87 88 89 90}

投稿2020/07/23 00:05

OZ-

総合スコア6

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

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

0

自己解決

コードAをコードBに下記のように組み込むことによって解決

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5[RequireComponent(typeof(AudioSource))] 6public class ColorOfset : MonoBehaviour 7{ 8 9 private Material _material; 10 protected string _shaderName = "ImageEffect/ColorOfset"; 11 12 private AudioSource audioSource; 13 public int resolution = 1024; 14 public Transform lowMeter, midMeter, highMeter; 15 public float lowFreqThreshold = 14700, midFreqThreshold = 29400, highFreqThreshold = 44100; 16 public float lowEnhance = 1f, midEnhance = 10f, highEnhance = 100f; 17 18 19 [SerializeField] 20 [Range(1, 1000)] 21 public float speed; 22 [SerializeField] 23 [Range(0, 1)] 24 public float powerA; 25 [SerializeField] 26 [Range(0, 1)] 27 public float powerB; 28 [SerializeField] 29 [Range(0, 1)] 30 public float powerC; 31 32 protected virtual void Awake() 33 { 34 Shader shader = Shader.Find(_shaderName); 35 _material = new Material(shader); 36 37 audioSource = GetComponent<AudioSource>(); 38 } 39 40 void OnRenderImage(RenderTexture source, RenderTexture destination) 41 { 42 UpdateMaterial(); 43 44 Graphics.Blit(source, destination, _material); 45 } 46 47 void UpdateMaterial() 48 { 49 // スペクトラムを取得 50 var spectrum = audioSource.GetSpectrumData(resolution, 0, FFTWindow.BlackmanHarris); 51 var deltaFreq = AudioSettings.outputSampleRate / resolution; 52 53 // スペクトラムから取り出した値を格納する変数 54 float low = 0f; 55 float mid = 0f; 56 float high = 0f; 57 58 // 周波数帯に応じて値を取り出す 59 for (var i = 0; i < resolution; ++i) 60 { 61 var freq = deltaFreq * i; 62 if (freq <= lowFreqThreshold) low += spectrum[i]; 63 else if (freq <= midFreqThreshold) mid += spectrum[i]; 64 else if (freq <= highFreqThreshold) high += spectrum[i]; 65 } 66 67 // 値を調整 68 low *= lowEnhance; 69 mid *= midEnhance; 70 high *= highEnhance; 71 low *= .15f; 72 mid *= .15f; 73 high *= .15f; 74 75 // ポストエフェクト側の変数に値を渡す 76 powerA = high; 77 powerB = mid; 78 powerC = low; 79 80 81 _material.SetFloat("_Speed", speed); 82 _material.SetFloat("_PowerA", powerA); 83 _material.SetFloat("_PowerB", powerB); 84 _material.SetFloat("_PowerC", powerC); 85 86 } 87 88 89 90}

投稿2020/07/23 00:00

OZ-

総合スコア6

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問