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

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

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

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

Q&A

解決済

1回答

935閲覧

Unityにおいて、シェーダーから法線を操作したい。

vinvinvidal

総合スコア18

Unity

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

0グッド

0クリップ

投稿2019/07/09 08:21

編集2019/07/09 11:22

前提・実現したいこと

シェーダーでモデルの法線を全て同じ方向に向け、インスペクタから操作しようとしているのですが、
どうにも狙った結果が得られません。

シェーダーのプロパティで用意した3つの変数
_NormalX
_NormalY
_NormalZ
をフラグメントシェーダーでnormalに直接代入して法線とする
i.normal = (_NormalX, _NormalY, _NormalZ);

法線の向きは全て同じになっているようなのですが
値を変えて見た目に変化が起きるのは_NormalZだけで、
_NormalX、_NormalYを変えても何も見た目に変化が起きません。

3つの値を変える事で自由に法線を操作したいと考えております。
御教示のほど、よろしくお願いいたします。

該当のソースコード

Shader "Custom/TestShader" { Properties { _MainTex("MainTex", 2D) = "white" {} _NormalX("_NormalX", Range(-1, 1)) = 0 _NormalY("_NormalY", Range(-1, 1)) = 0 _NormalZ("_NormalZ", Range(-1, 1)) = 0 } SubShader { Tags { "Queue" = "Geometry" "RenderType" = "Opaque" } Pass { Tags { "LightMode" = "ForwardBase" } CGPROGRAM #include "UnityCG.cginc" #include "AutoLight.cginc" sampler2D _MainTex; float _NormalX; float _NormalY; float _NormalZ; #pragma target 5.0 #pragma vertex vert #pragma fragment frag struct vertex_input { float4 pos : POSITION; half3 normal : NORMAL; float2 uv : TEXCOORD0; }; struct vertex_output { float4 pos : SV_POSITION; half3 normal: NORMAL; float2 uv : TEXCOORD0; }; //頂点シェーダ vertex_output vert(vertex_input i) { vertex_output re; re.uv = i.uv; re.pos = UnityObjectToClipPos(i.pos); re.normal = UnityObjectToWorldNormal(i.normal); return re; } //フラグメントシェーダ fixed4 frag(vertex_output i) : SV_Target { fixed4 re; re = tex2D(_MainTex, i.uv); i.normal = (_NormalX, _NormalY, _NormalZ); half d = dot(i.normal , normalize(_WorldSpaceLightPos0.xyz)); re *= d; return re; } ENDCG } } }

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

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

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

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

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

guest

回答1

0

ベストアンサー

HLSLリファレンスに下記のような記述がありました。ご質問者さんのコードもこうなってしまっていませんかね?

Comma Operator
The comma operator (,) separates one or more expressions that are to be evaluated in order. The value of the last expression in the sequence is used as the value of the sequence.

カンマ演算子
カンマ演算子(,)は順番に評価される一つ以上の式を区切るものです。一番最後の式の値が、この一連の式全体の値となります。

Here is one case worth calling attention to. If the constructor type is accidentally left off the right side of the equals sign, the right side now contains four expressions, separated by three commas.

注意すべき一例として、イコール記号の右に書くべきコンストラクタの型をうっかり忘れてしまうと、右辺は(float4を生成する式ではなく)3つのカンマで区切られた4つの式ということになってしまいます。

HLSL

1// Instead of using a constructor 2float4 x = float4(0,0,0,1); 3 4// The type on the right side is accidentally left off 5float4 x = (0,0,0,1);

The comma operator evaluates an expression from left to right. This reduces the right hand side to:

カンマ演算子は左から右へと式を評価していきます。結果として右辺は:

HLSL

1float4 x = 1;

HLSL uses scalar promotion in this case, so the result is as if this were written as follows:

HLSLはこの場合右辺のスカラーを昇格させますので、結果として以下のように書いたのと同様の結果になります:

HLSL

1float4 x = float4(1,1,1,1);

In this instance, leaving off the float4 type from the right side is probably a mistake that the compiler is unable to detect because this is a valid statement.

この例では、右辺に「float4」が欠落していたのはミスによるものと思われますが、式として有効であるためにコンパイラは誤りとして検出することができません。

投稿2019/07/09 10:16

Bongo

総合スコア10807

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

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

vinvinvidal

2019/07/09 11:20

丁寧な御回答ありがとうございます。 御教示頂いた通りでした、自分の無知を恥じるばかりです。 道は長いですが、拝借した御知恵を糧に精進して参りたいと思います。 重ねて御礼申し上げます、本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問