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

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

ただいまの
回答率

90.53%

  • C#

    7066questions

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

  • Unity

    3966questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

WebCamTextureを使ってRGBの値をリアルタイムで変更したいです。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 613

tig526

score 1

これで指定キーを押したら指定したRGBの値に変更するというコードを書きたいのですが、よくよくは白黒やセピアのようなものにしたいとも思ってますが初歩的なところで躓いてしまい先に進めません。よろしければヒントでもいいのでいただけると幸いです。よろしくお願いします。

public int Width = 1920;
public int Height = 1080;
public int FPS = 30;

public int mainCamNumber = 0;

public GameObject b;
public GameObject a;

// Use this for initialization
void Start()
{

WebCamDevice[] devices = WebCamTexture.devices;

WebCamTexture webcamTexture = new WebCamTexture(devices[mainCamNumber].name, Width, Height, FPS);
webcamTexture.deviceName = devices[mainCamNumber].name;

a.GetComponent<Renderer>().material.mainTexture = webcamTexture;
b.GetComponent<Renderer>().material.mainTexture = webcamTexture;

webcamTexture.Play();
}

void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
{
Debug.Log("Space");
R();
}
}
}

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

WebCamTextureと別に加工後画像用のRenderTextureを作って、Blitで加工しつつコピーするというのはどうでしょう?

キャプチャー用スクリプトを下記のようにしてみました。

using UnityEngine;

public class WebCamController : MonoBehaviour {
    public int Width = 1920;
    public int Height = 1080;
    public int FPS = 30;

    public int mainCamNumber = 0;

    public GameObject b;
    public GameObject a;

    public Material filterMaterial; // 追加...加工用マテリアル

    private WebCamTexture webcamTexture; // 追加...加工前テクスチャ
    private RenderTexture filteredTexture; // 追加...加工後のテクスチャ

    // Use this for initialization
    void Start()
    {

        WebCamDevice[] devices = WebCamTexture.devices;

        webcamTexture = new WebCamTexture(devices[mainCamNumber].name, Width, Height, FPS); // 変更...webcamTextureをインスタンス変数にする
        webcamTexture.deviceName = devices[mainCamNumber].name;

        filteredTexture = new RenderTexture(webcamTexture.width, webcamTexture.height, 0); // 追加...webcamTextureと同サイズのテクスチャを用意

        a.GetComponent<Renderer>().material.mainTexture = filteredTexture; // 変更...webcamTextureの代わりにfilteredTextureをセット
        b.GetComponent<Renderer>().material.mainTexture = filteredTexture; // 変更...webcamTextureの代わりにfilteredTextureをセット

        webcamTexture.Play();
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.Space)) // 変更...変化を分かりやすくするため、GetKeyDownの代わりにGetKeyを使用
        {
            {
                Debug.Log("Space");
                Graphics.Blit(webcamTexture, filteredTexture, filterMaterial); // 変更...キーが押されている場合はwebcamTextureをfilterMaterialを通してfilteredTextureにコピーする
            }
        }
        else
        {
            Graphics.Blit(webcamTexture, filteredTexture); // 追加...キーが押されていない場合はwebcamTextureをそのままfilteredTextureにコピーする
        }
    }
}

さらに下記のようなシェーダーを用意して、

Shader "Custom/TintShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _TintColor ("Tint Color", Color) = (1.0, 0.0, 0.0, 1.0)
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            uniform fixed4 _TintColor;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);

                col.rgb = dot(col.rgb, float3(0.3, 0.59, 0.11)) * _TintColor; // (0.3, 0.59, 0.11)との積和をとってグレースケール化した上で、_TintColorと掛けて着色

                return col;
            }
            ENDCG
        }
    }
}

これをセットしたマテリアルを作り、

マテリアル

キャプチャー用スクリプトに参照させました。

キャプチャースクリプト

画像の加工に関しては、マニュアルで紹介されている様々なテクニックが応用可能かと思います。
セピアトーンに関してですが、今回のようにグレースケール化して着色するだけでもいいかもしれませんが、こちらこちらを見た感じですと、ちゃんと個々の色成分を利用した方がきれいな仕上がりになりそうです。

[追記]
Legacy Image Effectsに収録されているSepiaToneEffect.shaderの場合は、モノトーンに対してセピア調になるよう色味を加減算しているようです。

Shader "Hidden/Sepiatone Effect" {
Properties {
    _MainTex ("Base (RGB)", 2D) = "white" {}
}

SubShader {
    Pass {
        ZTest Always Cull Off ZWrite Off
                
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"

uniform sampler2D _MainTex;
half4 _MainTex_ST;

fixed4 frag (v2f_img i) : SV_Target
{    
    fixed4 original = tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(i.uv, _MainTex_ST));
    
    // get intensity value (Y part of YIQ color space)
    fixed Y = dot (fixed3(0.299, 0.587, 0.114), original.rgb);

    // Convert to Sepia Tone by adding constant
    fixed4 sepiaConvert = float4 (0.191, -0.054, -0.221, 0.0);
    fixed4 output = sepiaConvert + Y;
    output.a = original.a;
    
    return output;
}
ENDCG

    }
}

Fallback off

}

[さらに追記]
すみませんでした。WebCamTexture, get correct resolution and RATIO. - Unity Answersによると、WebCamTextureの正しい解像度は少し待たないと取得できないという罠がある様子でした。間違った解像度でfilteredTextureを作ってしまったためひどい結果になったようです。
キャプチャー用スクリプトに解像度がまともになるまでしばらく待機させるよう変更を加えてみましたが、こちらではいかがでしょうか?

using UnityEngine;

public class WebCamController : MonoBehaviour {
    public int Width = 1920;
    public int Height = 1080;
    public int FPS = 30;

    public int mainCamNumber = 0;

    public GameObject b;
    public GameObject a;

    public Material filterMaterial; // 加工用マテリアル

    private WebCamTexture webcamTexture; // 加工前テクスチャ
    private RenderTexture filteredTexture; // 加工後のテクスチャ

    // Use this for initialization
    void Start()
    {

        WebCamDevice[] devices = WebCamTexture.devices;

        webcamTexture = new WebCamTexture(devices[mainCamNumber].name, Width, Height, FPS); // webcamTextureをインスタンス変数にする
        webcamTexture.Play();
    }

    void Update()
    {
        // 追加...テクスチャ解像度が適正に取得できるまで待機
        if (filteredTexture == null)
        {
            if (webcamTexture.width < 100)
            {
                Debug.Log("Please wait...");
                return;
            }
            else
            {
                Debug.LogFormat("WebCamTexture resolution: ({0}, {1})", webcamTexture.width, webcamTexture.height);

                filteredTexture = new RenderTexture(webcamTexture.width, webcamTexture.height, 0); // webcamTextureと同サイズのテクスチャを用意

                a.GetComponent<Renderer>().material.mainTexture = filteredTexture; // webcamTextureの代わりにfilteredTextureをセット
                b.GetComponent<Renderer>().material.mainTexture = filteredTexture; // webcamTextureの代わりにfilteredTextureをセット
            }
        }

        if (Input.GetKey(KeyCode.Space)) // 変化を分かりやすくするため、GetKeyDownの代わりにGetKeyを使用
        {
            {
                Debug.Log("Space");
                Graphics.Blit(webcamTexture, filteredTexture, filterMaterial); // キーが押されている場合はwebcamTextureをfilterMaterialを通してfilteredTextureにコピーする
            }
        }
        else
        {
            Graphics.Blit(webcamTexture, filteredTexture); // キーが押されていない場合はwebcamTextureをそのままfilteredTextureにコピーする
        }
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/17 19:38

    リンクや画像で丁寧な説明ありがとうございます
    さらに技術力の向上を目指したいと思います。

    キャンセル

  • 2017/09/18 22:36

    重ねて質問もうしわけありません。
    webカメラの解像度が著しく低下するのですが
    改善方法はありますか。

    キャンセル

  • 2017/09/18 23:25

    すみません、解像度が正しく取れていなかったようです。修正案を追記してみましたがいかがでしょう?

    キャンセル

  • 2017/09/18 23:58

    ありがとうございます。
    正常に動作しました。

    キャンセル

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

  • ただいまの回答率 90.53%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    7066questions

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

  • Unity

    3966questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。