Jump to content
  • Advertisement
Sign in to follow this  
L. Spiro

smooth/flat (GLSL)

This topic is 2871 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In GLSL, vertex shaders have the ability to create new global values which are sent to pixel shaders. For each fragment being processed, the values sent to that fragment is the result of interpolating between each of the 3 values set by each of the vertices in that triangle.

#1:
Does HLSL have this ability?

#2:
GLSL supplies the keywords smooth and flat to indicate how these values will be interpolated across the face of the triangle and sent down to each fragment generated on the triangle face.
Does HLSL have this mechanism?


L. Spiro

Share this post


Link to post
Share on other sites
Advertisement
#1 It's standard behaviour, all values passed to pixel (fragment) shaders are interpolated between vertex points.

Not sure about #2

Share this post


Link to post
Share on other sites
Can I see an example of how a vertex shader passes arbitrary data to a pixel shader?
I found no mention in my book nor online tutorials. They always consider this advanced and ignore it. I am talking about HLSL here.


Are the vectors re-normalized for each fragment?


L. Spiro

Share this post


Link to post
Share on other sites
Yes, newer version of directx (dx10+) allow the pixel shader to indicate how stream in will be interpolated. Labeling a pixel shader input (floating point value) with nointerpolation storage class will prevent interpolation for that value. All pixels for the triangle will receive the value from the leading vertex. Documentation here This would be considered the same as 'flat' while by default the values are interpolcated 'smooth'.

Passing data between shader stages is pretty consistent across the API, though you'll have to read up on all of the rules. Typically the safest thing to do is to use a structure that the vertex shader returns and the pixel shader accepts to their functions.

Share this post


Link to post
Share on other sites
Here's an example to illustrate how it works:

//Struct of values you want your vertex shader to pass to your pixel shader.
//These will be interpolated between the vertex points of the triangle.
struct PS_IN
{
float4 Position : SV_POSITION; //DX10+ uses SV_POSITION, DX9 uses POSITION
float3 Normal : TEXCOORD0;
...
};

//Vertex Shader
PS_IN VS( VS_IN input )
{
//Create the struct you want to pass to PS
PS_IN output = (PS_IN)0;

//Add data
output.Normal = normalize(mul(input.Normal, (float3x3)matWorld));
output.Positon = mul(input.Position, matWorldViewProjection);
...

return output;
}

//Pixel Shader
PS_OUT PS_Textured( PS_IN input )
{
//Access interpolated values:
float3 normal = normalize(input.Normal);
...
}

Share this post


Link to post
Share on other sites
So if the structure has the same member names, what if they are in a different order?
The pipeline will reshuffle them so that they still match up?
Or is it going by the offset into the structure + matching name?


Also, what if these are instead globals?
If I declare a global set by the vertex shader and a global with the same name read by the pixel shader, the result is the same?
And again, it would not matter in which order the globals are declared between the vertex shader and the pixel shader right? The processor will just magically know that the global with this name from the vertex shader is meant to be used for the value in the pixel shader with the same name, right?


Thank you,
Yogurt Emperor

Share this post


Link to post
Share on other sites
You must maintain the same order between stages. The D3D debug layer will provide you with error messages about miss matched stream inputs if you don't provided them in the same order. There is no magic here.

Globals are constants - you can't interpolate them, and they don't vary per pixel or per vertex.

Stream data is the only way to transfer information between shader stages. Global constants cannot be changed by a shader program and are unique per shader stage.

Share this post


Link to post
Share on other sites
I see.

I am making a new shading language that allows a once-written shader to run equally well on OpenGL, DirectX, Nintendo Wii, and PlayStation 3.

I need the lowest common denominator between each language.

OpenGL allows applying in and out to globals to indicate that they will be passed from the vertex shader to the pixel shader. Apparently DirectX has no such mechanism and instead you must pass the same structure in and out.


But I guess translating between these two systems is not so difficult.
Especially because I can just use the same structure and make it a global out in the vertex shader and a global in in the pixel shader.


Thank you,
Yogurt Emperor

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!