Sign in to follow this  

Lighting in 2D with Direct3D using SlimDX

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

First and foremost, I can handle all the actual drawing in Direct3D and have done it before, so none of this is a problem. What I am having a problem with is lighting.

I've read many tutorials that focus on lighting in a 3D environment and can't seem to get it to apply to my 2D world on large scale. So my first question is, does anyone have any good tutorials or books on lighting (possibly including setting up the camera as well, as this is my big problem with setting up lighting to work properly) specifically in a 2D environment? I know this first question is a lot to ask for, so here's my other one.

Rather than going with a complex lighting, I decided on using another type of method using simple lightmaps. I didn't want to go terribly complex with this, so I created a sample lightmap as seen on the first link below. My goal was to make it look something like the 2nd link (done in photoshop using, multiply filter and opacity set to 90%). However, I can only seem to get it at best to look like the 3rd link. My code for drawing the lightmap is below, can anyone give me any pointers on how to make it look more like the 2nd link?

Also I do need to mention, for the 1st result (3rd image), to get the correct opacity, I did have to change the alpha values for the drawmap to 20. While the inverted image has no change in opacity.

Please ignore changes in the background tiles, I just generated a random multi-colored floor for testing purposes.

My sample lightmap:


What I want to look like:


What it does look like:


Without the lightmap:


Inverted lightmap is almost what I want:


The drawing code (createmap/drawmap just draws multicolored rectangles at 32x32 intervals for the size of the form):


Public Structure ColorVertex
Public Position As Vector4
Public Color As Integer
Public TexturePos As Vector2
End Structure

Public Structure Vertex
Public Position As Vector4
Public TexturePos As Vector2
End Structure

Shared Sub Main()
form = New RenderForm("Test Build " & My.Application.Info.Version.ToString())
form.MaximizeBox = False
form.FormBorderStyle = FormBorderStyle.FixedSingle
form.ClientSize = New Size(800, 608)

'Create a device passing the device and form.
_Device = CreateDevice(form)

CreateMap()

Dim lightMap As Texture = Texture.FromFile(_Device, "lightmap.png")
Dim lightVertices() As Vertex = {
New Vertex() With {.Position = New Vector4(0, 0, 0, 1), .TexturePos = New Vector2(0, 0)},
New Vertex() With {.Position = New Vector4(800, 0, 0, 1), .TexturePos = New Vector2(1, 0)},
New Vertex() With {.Position = New Vector4(0, 608, 0, 1), .TexturePos = New Vector2(0, 1)},
New Vertex() With {.Position = New Vector4(800, 608, 0, 1), .TexturePos = New Vector2(1, 1)}
}

MessagePump.Run(form,
Sub()
_Device.Clear(ClearFlags.Target, Color.Black, 1.0F, 0)
_Device.BeginScene()

DrawMap()

_Device.SetRenderState(RenderState.AlphaBlendEnable, True)
_Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha)
_Device.SetRenderState(RenderState.DestinationBlend, Blend.One)

_Device.VertexFormat = VertexFormat.PositionRhw Or VertexFormat.Texture1
_Device.SetTexture(0, lightMap)
_Device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, lightVertices)

_Device.EndScene()
_Device.Present()
End Sub
)

For Each item As Object In ObjectTable.Objects
item.dispose()
Next
End Sub





If you need any of my other source for this project let me know. I only included what I thought was relevant.

Share this post


Link to post
Share on other sites
Sorry about that, my IP is allowed on the hotlink protection so I always forget. The images should be fixed now. If not, each image is click-able to a bigger version. If that still doesn't work, I'll upload them to somewhere else.

Share this post


Link to post
Share on other sites
You need a 'multiply' blend state (ie. you multiply your full colour texture by your lightmap texture). I'm not familiar with the VB syntax for that, but you'll need something like:


instead of:
_Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha)
_Device.SetRenderState(RenderState.DestinationBlend, Blend.One)

something like:
_Device.SetRenderState(RenderState.SourceBlend, Blend.DestinationColor)
_Device.SetRenderState(RenderState.DestinationBlend, Blend.Zero)


Share this post


Link to post
Share on other sites
Thank you for the response. Don't worry about the difference in languages. I am familiar with C# and C++ as well as VB. I just prefer VB.

WOW! That is exactly what I was going for! Thank you so much. Could you perhaps tell me how or why that is a multiply blend state? I guess I should probably check the DirectX documentation <_<.

Thanks again! :D

Share this post


Link to post
Share on other sites
Quote:
Original post by BigRedPK
WOW! That is exactly what I was going for! Thank you so much. Could you perhaps tell me how or why that is a multiply blend state? I guess I should probably check the DirectX documentation

The blend equation is a bit tricky to explain, but it's basically:

finalPixelColour = (sourceColour * sourceFactor) + (destColour * destFactor)

'sourceColour' is the colour from whatever you're drawing, in this case it's the colour from your lightmap.

'destColour' is whatever is already in the backbuffer/framebuffer that you're blending with.

'sourceFactor' and 'destFactor' are the ones you can control, via RenderState.SourceBlend and RenderState.DestinationBlend respectively.

Since you want lightmap * colourmap, we set 'sourceFactor' to be DestinationColor (this does the multiplication in the first half of the equation). Then we set the destFactor to Zero so that the right side of the equation has no effect. The final equation becomes:

finalPixelColour = (lightmapColour * framebuffer) + (framebuffer * 0)

HTH.

Share this post


Link to post
Share on other sites

This topic is 2661 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this