Jump to content
  • Advertisement
Sign in to follow this  

managed d3d (vb.net) simple diffuse shader looks like toon shading?

This topic is 2647 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

Hello everyone,

i'm using vb.net and managed d3d to make a converter of some game 3d files to the known obj file format. i used to make maxscript but decided to change to a standalone app.

importing data from the binary files was pretty easy, i've dealt with d3d before, and so was rendering stuff on screen. but then i wanted to use environment reflections, normal and specular maps, so i turned to shaders.

i have to admit, making a shader work for the first time was a pain, but finally i got it right. i'm passing all the parameters and matrices needed to the shader, and the result shows up. that's when the problem kicks in! the shader i have in the screenshots is a simple gray diffuse shader, and it comes up like toon shading, where black areas are in the shadow from the light, and white are lit. there's not smooth shading at all, and this happens with any of the 5 different shaders i've tried to use. i have to note that i tried used shaders i found over the internet, then made my own using shaderFX in max, all ending up in the same result...

standard d3d pipeline:

simple diffuse shader:

i've made sure the normals are imported correctly, i've also tried different computers/drivers, all the same.

btw the models are from nfs shift 2.

has anyone seen anything like that before? any ideas/tips?

toon shading is really not what i want to do right now :D

Share this post

Link to post
Share on other sites
Maybe you accidentally (although unllikely) use fixed pipeline? Try

DeviceInterface->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);

and see if that solves the problem.

Share this post

Link to post
Share on other sites
I've tried turning on/off all my initialisation parameters to see what's happening but nothing changed. since we'd reach a point when i'd have to show what's done, here's my current initialisation:

graphicsDevice.RenderState.ZBufferEnable = True
graphicsDevice.RenderState.Lighting = True
With graphicsDevice.SamplerState(0)
.MinFilter = TextureFilter.Linear
.MagFilter = TextureFilter.Linear
End With
With graphicsDevice.Lights(0)
.Type = LightType.Directional
.Diffuse = System.Drawing.Color.White
.Ambient = System.Drawing.Color.Black
.Specular = System.Drawing.Color.White
.Position = New Vector3(5.0F, 5.0F, 1.0F)
.Direction = New Vector3(-2.0F, -3.0F, -1.0F)
.Enabled = True
End With

the way i pass a value to the shader is through a handle:

carShader = Effect.FromFile(graphicsDevice, Application.StartupPath & "\diffuse.fx", Nothing, Nothing, ShaderFlags.None, Nothing)
h_tech = carShader.GetTechnique("Complete")
carShader.Technique = h_tech
h_WorldViewProj = carShader.GetParameter(Nothing, "wvp")
carShader.SetValue(h_WorldViewProj, tempmatrix)

and render loop is something like:

graphicsDevice.Clear(ClearFlags.Target Or ClearFlags.ZBuffer, System.Drawing.Color.Gray, 1.0F, 0)
<here i pass matrices and light position to the shader>

'then i loop through all the primitives of all the meshes (mesh,prim)
graphicsDevice.SetStreamSource(0, myscene.meshes(mesh).vb, 0)
graphicsDevice.Indices = myscene.meshes(mesh).ib(prim)
Dim numpasses As Integer = carShader.Begin(FX.DoNotSaveShaderState)
For pass As Integer = 0 To numpasses - 1
graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numverts, 0, numfaces)


i really can't trace where the problem is...
Edit: i just tried with a teapot mesh in case it was a normals problems, but it's doing exactly the same thing.

Share this post

Link to post
Share on other sites
I usually just use one or two triangles by hand when debugging a shader. Are you sure the normals are ok? Every vertex should have actually one normal (so it tyically is not the normal of the plane that the triangle lies in). So every triangle should have three different normals.if the two triangles share an edge you would end up with 3 different normals (assuming the triangles are not in the same plane).

Share this post

Link to post
Share on other sites
You set fixed function parameters (GraphicsDevice.Lights(0)) and then use a shader. If you use a shader you have to provide all information through shader parameters (material, light, etc), just like you set the wvp parameter now.

I assume the latter is correct (tempmatrix), since the rendering at least transforms the car correctly. But for lighting you (normally) have to submit also the world (or world inverse transpose) matrix to transform the normals correctly. Currently, we only see you set one shader parameter. Anyway, we don't know for sure what your shader expects. Could you please show us the full diffuse.fx shader code please - or at least the shaders from that "Complete" technique - and all the parameters you set ? That should clarify things.

Also: When working with shaders, get back the error string. Even if it compiles, there might be relevant warnings.

As an aside, this is a bit weird:

graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numverts, 0, numfaces)

As I understand you draw the same thing twice. This is superflous. Either use Mesh.DrawSubset or a (manual) DrawIndexPrimitive.

Also: If you don't already know: With PIX you can debug your rendering quite fine.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!