I am writing a pixelshader for terrain coloring and I am selecting my coor based on a number of different parameters, such a normal vector, 3d position and up to four noise functions, which define things as humidity, terrain type etc.
The terrain is one huge mesh, optimized as a ROAM, and each vertex has the properties mentioned above. There are formsts for storing normal, position, color or some other combination, but there are not enough for my need.
I remember reading somewhere about defining your own format, but I can not find it again and the last time i tried, it didnt work.
Can someone suggest where I should read about this
An extra question is... the position is never interpolated (before being passed to the pixelshader), as are the normal, color and texture coordinates This means that I always need to store the poxition two places in a vertex, to get the interpolated 3d position over into the pixel shader, so I can use it for color selection

Custom vertex format
Shokino
I am coding c# managed directx and tried the folowing, which doesn't work. I was expecting a solid red, but get a solid black instead.
I define my own vertex format as
public
struct ProceduralvertexFormat{
public Vector3 Position; public Vector3 Normal; public Vector4 Noise0; public ProceduralvertexFormat(Vector3 position, Vector3 normal, Vector4 noise0){
Position = position;
Normal = normal;
Noise0 = noise0;
}
public static readonly VertexFormats Format = VertexFormats.Position | VertexFormats.Normal | VertexFormats.Texture0;}
It is ment to hold a position, normal and a texture0.
I create a number of vertices, with valid positions and normals, but with a fixed value of Vector4(1,0,0,1) for the noise (in the test the color).
new ProceduralvertexFormat(p, n,new Vector4(1,0,0,1));In my effect file, I use the normal vertexshader and only define anything else for the pixelshader, which is
float4 PixelShaderPhong(float4 t:TEXCOORD0):COLOR
{
return t;
}
I render with the folowing and something else. Like setting buffers etc etc. The code works fine, apart from the solid black and not red.
device.VertexFormat =
ProceduralvertexFormat.Format;device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0.......I was expecting to see the texture coordinate zero holding (1,0,0,1), and was expecting to see the shader output it as a color, which would be red. It is black. What exactly do i do wrong here
A folowup question would be how the positions, normals, colors and texture coordinates should be ordered. How does the renderer know if the first bit of data in my structure is a position or a texture coordinate I only define that there IS such elements, but not where they are. Secondly. Which parameters are passed on to the pixelshader, and which are not The position for one, is not. I need it so I will have to move it out as a texture coordinate or something else, but it would be nice to know exactly which can be used and which can not.
RJMPhD
I did already look at it, and as far as I can see, I am doing the same thing.
The tutorial doen't get into details about the order of the position, normal, color etc.
I have been looking far and wide, and dint fine any in depth info on this. Even on msdn, it seems that all that is written, is that FVF exists. I assume that there is some techinal info on this, but I havn't been able to locate it.
Deeps_123
It explains it pretty well and you should get your code working from that.
If you have any more questions, please don't hesitate to ask.
I hope this helps.
Take care.
TheQuietShadow
I'm not used to managed code so I've reproduce your case in HLSLWithoutEffects which uses vertex declaration rather than FVF and it works well. I don't know what the problem is with your code but I think there's no prolem to do what you're expecting to do. Consider using Pix to test if the varyings you're receiving in the shaders are correct.
>>A followup question would be how the positions, normals, colors and texture coordinates should be ordered
It seems to me that your data should be ordered in the same order as the define values (D3DFVF_XYZ, D3DFVF_NORMAL,....) are.
>>How does the renderer know if the first bit of data in my structure is a position or a texture coordinate
I think it's also hard coded based on that definition values order.
>> Which parameters are passed on to the pixelshader, and which are not
You're the one that decide which parameters are passed to the shader when you write pixel shader inputs varyings. No parameter (except unifoms of course) are passed directly from the vertex varying stream to the pixel shader. You should output what you need in the pixel shader from the vertex shader. That is why I was telling you that you don't need to set POSITION two times in the vertex buffer.
>>I need it so I will have to move it out as a texture coordinate or something else
Yes, output positions from the vertex shader in a texture coordinate register and use it in the pixel shader.
Finally, I would recommend you to try vertex declaration. It is a powerful and fully customizable format descriptor. Furthermore, converting from FVF to vertex declaration is straightforward and well documented.
Luca Beretta
After some trials and errors I have determined that the order matter (not sure why or even if it's true)
Here is the order it expect to get it's value :
Position x,y,z (sometime with a w)
Color (diffuse one DWORD)
Normal x,y,z
Texture0 u1,v1
Texture1 u2,v2
...
You can set as many as 8 index of texture...
When you create the VertexBuffer you tell then all the FVF:: flags in that order
You can skip one or many line if you don't set a color, you skip that line and flag
But keep that order just to be safe
The system knows what to expect because you call pDevice->SetVertexFVF( your flags go here )
Before you call draw primitive...
If it's in the shader your declaration of the VS will be in that order...
The TEXTURE0 may have only 2 float value...
You should store value like 0.1 0.2 0.3 0.4 and see with Pix where the value end up in the register...
What you try to do look like per-pixel lighting so maybe this link could help :
http://www.zanir.szm.sk/dx10-19.html
Peter Chapman
Vertexdeclaration was the way to go. It is quite obvious how things are ordered, and it works for me now. I have a position, normal and two floats, each in its own texture coordinate.
A quistion though.. all the vertex and pixel variables are float4, arent they So when I declare something as float1, i am actually wasting 3 perfectly good floats in my texture coordinates. Would it be more effective to put both floats in the same texture coordinate and then acccss them through texcoord.x and texcoord.y
SUMEET_1876
- I think you're speaking about "Vertex Declaration" which defined vertex buffers layout. It allows to build your own custom format for both fixed and programmable pipelines. There's a lot of documentation about that in Dx9 SDK, it should not be a problem.
>>This means that I always need to store the position two places in a vertex...
Seems that you're using shaders, so you only need to store the position between the vertex and the pixel shader. The is no need to send positions a second time to the vertex shader, you'll only need to output it from the vertex shader. Furthermore, you'll probably do some pre-computations per vertex before sending raw positions per pixels. The TEXCOORDn semantic is usualy used for data like this one and are interpolated like texture coordinates are. I'm not sure why, I presume this is because COLORn is clamped and texture aren't.
Skippy1313
Indeed shader registers are float4, but that's not really important as long as you've got enough registers to compile your shader. The important waste would be to allocate a vertex buffer of 16bytes (float4) to use only 4bytes(float1). Multiply this waste per the number of vertices in the buffer and you got a huge waste. But that's not the case, or at least that shouldn't be. Indeed, the vertex declaration is build with a float and the vertex buffer is filled with floats. The GPU is then responsible at shader execution time to expand the float into a float4 register.
>> Would it be more effective to put both floats in the same texture coordinate and then acccss them through texcoord.x and texcoord.y
No it would not be more efficient because it prevents the compiler to do some vectorizations optimisations as it is sometime explained in high level shader languages optimization guides.