Jump to content

  • Log In with Google      Sign In   
  • Create Account

We need your feedback on a survey! Each completed response supports our community and gives you a chance to win a $25 Amazon gift card!


Shaders implementation


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
25 replies to this topic

#1 Yura   Members   -  Reputation: 263

Like
0Likes
Like

Posted 28 December 2012 - 08:26 AM

Hi, please help me resolve next problems:

 

1) how to draw triangle list and line list (like this http://imageshack.us...capture2pu.png/)

with different colours from one vertex buffer? I have 1 buffer which contains points and colors. I have 2 index buffers for it (for line list and triangle list). I want to draw triangles with color from buffer and white (or black or whatever) lines.




2) I've tried to implement shaders to make different front and back triangle colors, but it doesn't work:


//drawing function:

 

private void RedrawPrimitives()
        {

            var effect = Effect.FromFile(d3dDevice, "Shader.fx", ShaderFlags.None);
            var technique = effect.GetTechnique(0);
            var pass = effect.GetPass(technique, 0);
            
            d3dDevice.VertexFormat = myVertexFormat;
            d3dDevice.VertexDeclaration = vertexDecl;

            d3dDevice.Clear(ClearFlags.Target, SharpDX.Color.White, 1.0f, 0);
            d3dDevice.BeginScene();

            effect.Technique = technique;
            effect.Begin();
            effect.BeginPass(0);

            d3dDevice.Indices = triangles;
            d3dDevice.SetStreamSource(0, vertices, 0, Marshal.SizeOf(typeof(Vertex)));
            d3dDevice.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, totalPointsCount, 0, totalPointsCount / 2);

            
            d3dDevice.Indices = lines;          
            d3dDevice.SetStreamSource(0, vertices, 0, Marshal.SizeOf(typeof(Vertex)));
            d3dDevice.DrawIndexedPrimitive(PrimitiveType.LineList, 0, 0, totalPointsCount, 0, totalPointsCount);

            effect.EndPass();
            effect.End();

            d3dDevice.EndScene();
            d3dDevice.Present();

            effect.Dispose();
            technique.Dispose();
            pass.Dispose();
        }

 

//and shader (which doesn't work)

 

sampler s0;

struct VertexShaderInput
{
    float4 Position : POSITION0;
	float4 Color : COLOR0;
	float4 face : VFACE;

    // TODO: add input channels such as texture
    // coordinates and vertex colors here.
};

struct VertexShaderOutput 
{
    float4 Position : POSITION0;
	float4 Color : COLOR0;

    // TODO: add vertex shader outputs such as colors and textureasdfasd
    // coordinates here. These values will automatically be interpolated
    // over the triangle, and provided as input to your pixel shader.
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
	VertexShaderOutput output;
	output.Position = mul(input.Position, input.Color);
	output.Color=input.Color;
    // TODO: add your vertex shader code here.

    return output;
}

float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
{
    float4 color = tex2D(s0, coords);
	color.rgb = color.r;

    return color;
}

technique Technique1
{
    pass Pass1
    {
		VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

 

 



Sponsor:

#2 mhagain   Crossbones+   -  Reputation: 8287

Like
0Likes
Like

Posted 28 December 2012 - 08:50 AM

1. What have you tried?

 

2. Define "doesn't work".  What happens?


It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#3 Yura   Members   -  Reputation: 263

Like
0Likes
Like

Posted 28 December 2012 - 09:32 AM

1. What have you tried?

2. Define "doesn't work". What happens?
Nothing happens! I can see only blank screen (white, to be exect). There are no compile exceptions. Without shaders everything works fine, I can build triangles and lines.
1. What I've tried and trying to do is written above. Сertainly not as a book says, but I think it is clear. If you need more information, just say what exactly you need and i'll post it here.

Edited by Yura, 28 December 2012 - 09:38 AM.


#4 NewDisplayName   Members   -  Reputation: 359

Like
2Likes
Like

Posted 28 December 2012 - 11:49 AM

I see that your PixelShader function is supposed to get a VertexShaderOutput as a parameter, but instead you're passing it this :

"float2 coords: TEXCOORD0". It should rather be "VertexShaderOutput coords".

 

Other than this, I would suggest to go through some HLSL examples from DirectX SDK and more from other good online references. That will definitely help.



#5 phil_t   Crossbones+   -  Reputation: 4109

Like
1Likes
Like

Posted 28 December 2012 - 08:22 PM

To explain NewDisplayName's post a little more: you're returning the COLOR0 semantic from your vertex shader, but you're not using COLOR0 as an input to your pixel shader. Instead you're using TEXCOORD0 (which wasn't even passed out from your vertex shader, so it will not contain valid values) and sampling from some texture.

Presumably you want to have COLOR0 as an input to your pixel shader (and perhaps just return that value as the output? Not sure, because I don't know what you're trying to do with the texture).

#6 Yura   Members   -  Reputation: 263

Like
0Likes
Like

Posted 29 December 2012 - 02:30 AM

Sory for troubling guys, but as you can see, I'm very new in shaders. I wrote a program on direct3d9 which is drawing some surface from triangle list primitives. I have made rotation functions, which allows me to rotate this surface. All of it is made without using any shaders and it works. It works nice, fast, but with one defect. This surface is half transparent. I've tried to blend alfa component, tried to set color in RGB mode but all without success. They are still half transparent. So, now I'm trying to fix it with help of shaders and to add new features - draw this primitives with different colors on front and back sides.

I've made some changes to my shader, now it works, but color is still half transparent. Somebody knows how to fix it?

Edited by Yura, 29 December 2012 - 07:22 AM.


#7 unbird   Crossbones+   -  Reputation: 6028

Like
1Likes
Like

Posted 30 December 2012 - 01:43 PM

Well disabling blending would be device.SetRenderState(RenderState.AlphaBlendEnable, false); then. I misunderstood that in your previous thread. Not sure if this actually solves your problem. Can you provide a screenshot and what other render states you used ? And since one can change render states with the effect framework, the shader file is relevant, too. (Please, don't delete code in your posts, rather update).

#8 Yura   Members   -  Reputation: 263

Like
0Likes
Like

Posted 02 January 2013 - 01:54 AM

Well disabling blending would be device.SetRenderState(RenderState.AlphaBlendEnable, false); then. I misunderstood that in your previous thread. Not sure if this actually solves your problem. Can you provide a screenshot and what other render states you used ? And since one can change render states with the effect framework, the shader file is relevant, too. (Please, don't delete code in your posts, rather update).


My image contains many colors, but it's ok, each point has it's own color and they might be different. The problems are:
1) As you can see, image is half transparent. Enabling/disabling alpha blend gives nothing.
2) Over the triangles I want to draw Lines from the same vertex buffer but with different color (white, for example). Drawing lines is not a problem, but how can I ignore their color, declarated in vertex buffer?

Render states, which I currently use:

 

d3dDevice.SetRenderState(RenderState.Lighting, 0); // Turn off D3D Lighting
d3dDevice.SetRenderState(RenderState.CullMode, Cull.None);
d3dDevice.SetRenderState(RenderState.FillMode, FillMode.Solid);
d3dDevice.SetRenderState(RenderState.AlphaBlendEnable, false);

 

 

and shader

 

struct VertexShaderInput
{
float4 Position : POSITION0;
float4 Color : COLOR0;
};

struct PixelShaderInput
{
float4 Color : COLOR0;
float face : VFACE;
};

struct VertexShaderOutput
{
float4 Position : POSITION0;
float4 Color : COLOR0;
};

float4x4 worldViewProj;

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;

output.Position = mul(input.Position, worldViewProj);
output.Color = input.Color;
output.Color.a = 0.0f;

return output;
}

float4 PixelShaderFunction(PixelShaderInput input) : COLOR0
{
float4 back = float4(200.0f, 0.0f, 0.0f, 0.0f);
//input.Color.a = 0.0f;

if(input.face>0)
{
return input.Color;
}
else
{
return input.Color;
}

}

technique Technique1
{
pass Pass1
{
VertexShader = compile vs_3_0 VertexShaderFunction();
PixelShader = compile ps_3_0 PixelShaderFunction();
}
}

 

 

Also I've tried to enable depth buffer (ZBuffer) but id didn't help. Picture was drawn same as without it.

 

d3dDevice = new Device(
                         d3d,
                         0,
                         DeviceType.Hardware,
                         panel1.Handle,
                         CreateFlags.HardwareVertexProcessing,                       
                         new PresentParameters()
                         {
                             Windowed = true,
                             SwapEffect = SwapEffect.Discard,
                             BackBufferFormat = Format.Unknown,
                             PresentationInterval = PresentInterval.Immediate,
                             BackBufferWidth = panel1.Width,
                             BackBufferHeight = panel1.Height,
                             EnableAutoDepthStencil = true,
                             AutoDepthStencilFormat = Format.D16
                         });

 

 

 

 

If you need more information, please let me know and I will post it

Attached Thumbnails

  • Capture123.PNG

Edited by Yura, 02 January 2013 - 02:28 AM.


#9 NewDisplayName   Members   -  Reputation: 359

Like
1Likes
Like

Posted 02 January 2013 - 02:49 AM

Yura,

 

Just check this method in your shader and see if you think this is how it should be (because I definitely don't think so).

 

float4 PixelShaderFunction(PixelShaderInput input) : COLOR0  // Use VertexShaderOutput
{
float4 back = float4(200.0f, 0.0f, 0.0f, 0.0f); // why?
//input.Color.a = 0.0f;
 
if(input.face>0)
{
return input.Color; // nothing
}
else
{
return input.Color; // nothing
}
 
}


#10 Yura   Members   -  Reputation: 263

Like
0Likes
Like

Posted 02 January 2013 - 03:02 AM

Yura,

 

Just check this method in your shader and see if you think this is how it should be (because I definitely don't think so).

 

float4 PixelShaderFunction(PixelShaderInput input) : COLOR0  // Use VertexShaderOutput
{
float4 back = float4(200.0f, 0.0f, 0.0f, 0.0f); // why?
//input.Color.a = 0.0f;
 
if(input.face>0)
{
return input.Color; // nothing
}
else
{
return input.Color; // nothing
}
 
}

I've implemented VFACE semantic. If I'm looking to a front of the primitive (face>0), I'm returning true vertex color, else, I'm returning red color (back). It works fine, I've just disabled it for a time, so, independent of VFACE I'm returning true color of vertex.

 

Thanks for suggestion!



#11 Yura   Members   -  Reputation: 263

Like
0Likes
Like

Posted 02 January 2013 - 03:06 AM

I've figured out with transparency. Problem was in my ViewPort. I've enabled ZBuffering and change the ViewPort MinZ and MaxZ values and it worked!) If someone interested in code, let me know, I can share.

 

Now, over the triangles I want to draw Lines from the same vertex buffer but with different color (white, for example). Drawing lines is not a problem, but how can I ignore their color, declarated in vertex buffer?



#12 NewDisplayName   Members   -  Reputation: 359

Like
1Likes
Like

Posted 02 January 2013 - 03:11 AM

I still don't get it.

 

Why are you passing this --> PixelShaderInput input

when you should be passing this --> VertexShaderOutput input

 

Also, please post your final code with the current status of problem.



#13 Yura   Members   -  Reputation: 263

Like
0Likes
Like

Posted 02 January 2013 - 03:27 AM

I still don't get it.

 

Why are you passing this --> PixelShaderInput input

when you should be passing this --> VertexShaderOutput input

 

Also, please post your final code with the current status of problem.

 

Maybe you're right. It's not logical. But problem is not here.

 

I have VertexBuffer filled with this struct:

[StructLayout(LayoutKind.Sequential)]
    struct Vertex
    {
        public Vector3 Position;
        public Color Color;
    }

 

 

How can I draw primitives, using this struct, but skipping it's color? 

For better understanding what I'm Trying to do: over the TriangleList primiteves I want to draw LineList from the same vertex buffer but with different color (white, for example). Drawing lines is not a problem, but how can I ignore their color, declarated in vertex buffer? Is it possible to do it without using shaders?



#14 NewDisplayName   Members   -  Reputation: 359

Like
1Likes
Like

Posted 02 January 2013 - 03:35 AM

For that your need to set your D3DFVF flags right.

Basically, without shaders your CUSTOMVERTEX structure needs to be setup with FVFs in such a manner that the color associated with that vertex gets bypassed.

Check this out for further reference --> http://msdn.microsoft.com/en-us/library/windows/desktop/bb172559(v=vs.85).aspx



#15 Yura   Members   -  Reputation: 263

Like
0Likes
Like

Posted 02 January 2013 - 04:14 AM

For that your need to set your D3DFVF flags right.
Basically, without shaders your CUSTOMVERTEX structure needs to be setup with FVFs in such a manner that the color associated with that vertex gets bypassed.
Check this out for further reference --> http://msdn.microsoft.com/en-us/library/windows/desktop/bb172559(v=vs.85).aspx


It's it! Setting
d3dDevice.VertexFormat = VertexFormat.Position;
is skipping the color and making lines white.

I don't want to trouble you more, but is it possible to make this lines thicker? They are very thin and when i use rotation they are partly absorbed by color triangles:

d3dDevice.SetStreamSource(0, vertices, 0, Marshal.SizeOf(typeof(Vertex)));            d3dDevice.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse;            
d3dDevice.Indices = triangles;            
d3dDevice.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, totalPointsCount, 0, totalPointsCount / 2);            
d3dDevice.VertexFormat = VertexFormat.Position;          
d3dDevice.Indices = lines;            
d3dDevice.DrawIndexedPrimitive(PrimitiveType.LineList, 0, 0, totalPointsCount, 0, totalPointsCount);

Look at the green side of picture, some lines are missing. They are absorbed

Attached Thumbnails

  • Capture4.PNG


#16 NewDisplayName   Members   -  Reputation: 359

Like
1Likes
Like

Posted 02 January 2013 - 04:23 AM

I think you're troubled by aliasing right now. Put a basic sampler state with min,mag,mip all LINEAR, in your shader, and then see if something changes.



#17 unbird   Crossbones+   -  Reputation: 6028

Like
1Likes
Like

Posted 02 January 2013 - 04:44 AM

Nice to see you're making progress.

 

No, he does not use texturing, so it's not a sampling artifact. I suspect something with the depth test (z-fighting): Lines and Quads are approximately at the same depth, but only approximately. Play around with the DepthBias render state .



#18 Yura   Members   -  Reputation: 263

Like
0Likes
Like

Posted 02 January 2013 - 05:54 AM

Nice to see you're making progress.

 

No, he does not use texturing, so it's not a sampling artifact. I suspect something with the depth test (z-fighting): Lines and Quads are approximately at the same depth, but only approximately. Play around with the DepthBias render state .

 

They are realy at the same depth. I'm drawing it from 1 vertexBuffer, just with different indexes. Their position is the same. I'm drawing tringles at first, then lines over them.

d3dDevice.SetStreamSource(0, vertices, 0, Marshal.SizeOf(typeof(Vertex)));            
d3dDevice.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse;            
d3dDevice.Indices = triangles;            
d3dDevice.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, totalPointsCount, 0, totalPointsCount / 2);            
d3dDevice.VertexFormat = VertexFormat.Position;          
d3dDevice.Indices = lines;            
d3dDevice.DrawIndexedPrimitive(PrimitiveType.LineList, 0, 0, totalPointsCount, 0, totalPointsCount);

 

 

Playing with DepthBias render state do not give any results...



#19 NewDisplayName   Members   -  Reputation: 359

Like
0Likes
Like

Posted 02 January 2013 - 06:06 AM

In addition to trying out suggestions from this, like I said before, you should also try to introduce some sampler state in your shader now.



#20 unbird   Crossbones+   -  Reputation: 6028

Like
1Likes
Like

Posted 02 January 2013 - 07:27 AM

Playing with DepthBias render state do not give any results...

I still assume it's a z-fighting problem. And I assume you're already using LessEqual for the ZFunc (this should be the default).

Oh my, I just realized this: Depth Bias (Direct3D 9). The devil's in the details:
The bias is not applied to any line and point primitive. However, this bias needs to be applied to triangles drawn in wireframe mode.

Alternative: Setup your WorldViewProjection to manually create a depth bias, e.g. use WVP * Matrix.Translation(0,0,-0.001f) or something. Edit: For the lines only!

Edited by unbird, 02 January 2013 - 07:28 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS