Skip to main content
GameDev.net gamedev.net
🔒 Locked

CG Shaders and data

Started by Winegums Mar 27, 2007 at 4:14 AM 4 replies 1.2k views
Original Post
Winegums
Winegums
I get the feeling this threads going to be bumped with new questions periodically by me, so i pre-emptivley apologise for that :) Ok, to business. I'm implimenting some CG shaders to render my terrain, and so far it's going well. I have a terrain class, which is a 2d grid with textures etc. Up until now i've simply activated/deactivated the shader around the theTerrain->Render() call in the draw loop. however now that i'm reaching the point where i want to pass vertex data to the fragment shader, and i'm not sure how to do this (i want to pass the height of a vertex, so i can then modulate the alpha of a texture by the height). the NVidia explanations don't seem to cover how to do this, and seeing as how debugging shaders seems to be far more difficult than debugging c++, i was hopeing someone could explain the methods involved. thank you for your time.
Poons
Poons
You can pass data to the cg shader, for example (in OpenGL) with
cgGLSetParameter1f(cgHeight, vertex.height);

before you can pass something you have to define a cgParameter and connect it with the variable in the shader.
CGParameter cgHeight;cgHeight = cgGetNamedParameter(name_of_your_shader, "height");

and the shader code would look like that:
void name_of_your_shader ( uniform float height, ...)
you humans are such dreamers. you dream that you´re clever. You dream that you´re important. You dream that you´re special. [the wee free men, terry pratchett]
Lord_Evil
Lord_Evil
I guess you don't intend to pass the data for each vertex via the cg runtime but rather want to pass vertex data from the vertex shader to the fragment shader.

Many do this by (ab)using texture coordinates or colors that will contain the needed values. Lets say you have one set of texture coorinates that are used as such. You now pass the height (or better the actual blending values) in the second set of texture coordinates and use it in your fragment shader. This way your values will also be interpolated by the rasterizer.

The reason why I'm telling you to pass the actual blending values is the much lower computation frequency of the vertex shader. Since your values will be interpolated by the rasterizer anyways you could shift some work from the fragment shader to the vertex shader which will be called less often.
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
Winegums
Winegums
thanks for the replies guys.

what would be the best way to create and use a variable that accessses the height data from the terrain? Passing the max height variable to the shader is fine since it's one float and it's constant, but obvioulsy passing the whole grid to the shader is the worst idea ever.


EDIT: wait...if im passing in vertex data to the VS anyway, could i grab that and forward it to the PS? Actually, how do i forward the VS output to the PS input? I know Lord_Evil suggests doing things on the VS to save bottlenecking, but I'm just interested in what my options are (for future reference if nothing).

DOUBLE EDIT: In the nehe example, the vertex shader function has the following declaration

vfconn main(appdata IN, uniform float4x4 ModelViewProj){}


is it advisable to move the view matrix into being a 'global' variable in the shader, rather than passing it into the function again and again? ie

uniform float4x4 ModelViewProj

vfconn main(appdata IN){}

[Edited by - Winegums on March 27, 2007 10:00:29 PM]
Lord_Evil
Lord_Evil
Quote:

what would be the best way to create and use a variable that accessses the height data from the terrain? Passing the max height variable to the shader is fine since it's one float and it's constant, but obvioulsy passing the whole grid to the shader is the worst idea ever.

I don't know if I can follow you here but you could store the heightmap as a texture and use a texture-lookup in the shader. You could provide an additional set of texcoords per vertex to index into the heightmap.

If you use static (non-deformable) terrain why don't you just access the height from the vertex' y-position?

Quote:

Edit: wait...if im passing in vertex data to the VS anyway, could i grab that and forward it to the PS? Actually, how do i forward the VS output to the PS input? I know Lord_Evil suggests doing things on the VS to save bottlenecking, but I'm just interested in what my options are (for future reference if nothing).

That depends on whether the data is uniform or varying. Uniform data can be passed as a parameter, varying (per vertex) data could be forwarded by (ab)using texture coordinates.

AFAIK in DX10 it will be possible to render the vertices to multiple color buffers so you could use them to pass additional per-fragment data. But I'd guess you don't use DX10 [smile].


Quote:

is it advisable to move the view matrix into being a 'global' variable in the shader, rather than passing it into the function again and again? ie

uniform float4x4 ModelViewProj

vfconn main(appdata IN){}

AFAIK the 'global' variable is in shader scope so if you change the shader the matrix would be lost. Also, rendering different models normally involves different ModelView matrices and thus you'd have to update it anyway.

If you're using OpenGL you could however directly access the OpenGL state from within the shader. But note that this would break D3D compatibility.
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
Winegums
Winegums
thanks very much for your replies. I'm at the point where I have my terrain texturing and blending between textures (passing a float from the VS to the PS to indicate weighting). Now it's time to light the terrain!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.