- Home /
Vertex Shader Properties Issu
I'm getting a Material doesn't have a float or range property '_Width' UnityEditor.DockArea:OnGUI() error for all of my properties and I don't know why. Can anyone see the problem?
Also if anyone knows what's wrong with this line I'd appreciate it **v.vertex = _Position + (_WidthDir x + _HeightDir y) _Width;*
Shader "Custom/PlanetShader" {
Properties {
_Position ("Position", Vector) = (0,0,0,0)
_WidthDir ("WidthDir", Vector) = (1,0,0,0)
_HeightDir ("HeightDir", Vector) = (0,1,0,0)
_Width ("Width", Float) = 1
}
SubShader {
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform float4 _Position;
uniform float4 _WidthDir;
uniform float4 _HeightDir;
uniform float _Width;
struct v2f{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_base v){
v2f o;
float4 x = float4(v.vertex.x, 0, 0, 0);
float4 y = float4(0, v.vertex.y, 0, 0);
v.vertex = float4(x,y,0,0);
v.vertex = _Position + (_WidthDir * x + _HeightDir * y) * _Width;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
half4 frag(v2f i) : COLOR{
return (0,0,0,.9);
}
ENDCG
}
}
}
Is the shader compiling? Can you post the line of code causing the missing _Width error?
If I remove lines 3-6 the errors go away. Yes it compiles. And if I remove line 30, I can see the mesh. But it looks like the error I was getting was caused by line 29 even though the compiler was throwing that bizarre set of errors.
Answer by tanoshimi · Sep 16, 2013 at 07:57 AM
Your problem is in the line:
v.vertex = float4(x,y,0,0);
because, instead of constructing a float4
from four float
parameters, x and y are themselves float4
s (as defined in the two preceding lines).
This statement is completely redundant anyway because v.vertex is reassigned in the following line, so you can just delete it altogether.
I removed line 29 and I no longer get the weird errors. But line 30 still doesn't work. If I comment it out I can see the mesh. If I don't uncomment it I can't see the mesh from any angle. With the params I'm passing in, it should just move its starting point to -2,-2,-2 and leave everything else the same. Is it possible to add and multiply vectors and floats like I'm doing?
It's possible, you're just defining x and y incorrectly. Try thinking about what the variables are. You've defined x and y as float4 values - this means they are 4 dimensional vectors, with each vector component being a float value. This is a good time to point out that, since you're only using one value of the 4 you've assigned (3 of them are just constant 0), this is terrible, TERRIBLE code. In shaders particularly, you want to cut down the amount of data you're storing as much as possible, so really, you only need to store x and y as float
values (without the 4), so you're only storing a single number.
As for the next part, line 29 does nothing (as you're reassigning it in line 30), so get rid of that. Line 30 has an issue because you're multiplying 2 float4s together. This will not do what you think, because it may do any one of: the cross product, the dot product, or ignore several values in one float4. This is not really desired behaviour. I expect what you actually want is to multiple the entire vectors _WidthDir and _HeightDir by the respective x and y values. Fortunately for you, the problem is actually the same as before - the very fact that x and y are defined as float4s. If you define them as float values, ins$$anonymous$$d of multiplying two vectors, you are multiplying a vector and a scalar, which, ins$$anonymous$$d of doing anything like the cross or dot product, just involves multiplying all the values in the vector by the scalar. For example, if you try to do: 2*{1,2,3,1} (where the {} defines the vector), you'll end up with: {2,4,6,2}.
In short, your problem is that you need to pay more attention to types. Types are incredibly important, and should not be taken lightly. To avoid this sort of issue in the future, you should try to think about exactly what your code is doing - ignoring actual values, and just thinking about the types. For example, when you assign v.vertex on line 30, you are doing:
Vector + (Vector*Vector + Vector*Vector) * Scalar.
It should be immediately obvious, having done that, that this is wrong, and that you actually want:
Vector + (Vector*Scalar + Vector*Scalar) * Scalar.
Line 30 "works" fine (in that it's syntactically correct), but it might not be doing what you want it to. But, seeing as you haven't actually said what you're trying to do, it's pretty hard for anyone to help you further! What exactly do you expect the shader to achieve? What are _WidthDir and _HeightDir? And why are you doing a lot of Float4x4 matrix multiplications when it seems like you only ever use one element of each matrix (i.e. only x in _WidthDir and only y in _HeightDir) - why not provide them in a single matrix, or provide them separately as individual scalar floats?
To translate the "starting point" by (-2,-2,-2) you need to pass in a _Position vector of (-2,-2,-2, 0) and set every other property at 0, which works for me.
Oh, and one last thing - you should probably be using float3s ins$$anonymous$$d of float4s. You're modifying vertex positions here, which are defined by a vector storing {x,y,z}. Since those are only 3 values, the 4th value in the float4 will just be truncated (removed), so you're wasting processing time doing anything with it.
Thanks everyone for the help. Looks like it was the W's that were causing all the problems. I've made sure they're always 1 and made x and y floats ins$$anonymous$$d of float4's and it appears to be working. In GLSL I only had to worry about xyz and never w, and I had just assumed it was always 0 and stayed 0. Hard coding it to 1 works. Thanks again.