Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / [STICKY] Learning to write Shaders

Author
Message
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 12th Apr 2009 23:11
Math89

That function should be very useful. Thanks.

No idea why I hadn't done something like that myself.

AtomR

That is a weird error. Any chance of posting a simple demo and media so I can test it?
Serial Velocity
15
Years of Service
User Offline
Joined: 24th Aug 2008
Location:
Posted: 13th Apr 2009 17:24
Hey,

I have been attempting to create a shader which creates an effect of night lights showing up on the back of a planet. I'm currently using this as a guide. So far i've had no success of implementing this into DBPro. This is the result i get:


Heres my shader:


Heres my DBPro source code:


Ive also attached a ZIP of the project file with media and everything.

Thanks for your help

Attachments

Login to view attachments
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 13th Apr 2009 22:54
Serial Velocity

I had to make two changes to your demo to get it to work:

1. in the .dba file, load and check the shader after the set display mode command (this command clears the video memory and I guess deletes the loaded shader - but doesn't seem to give an error message );

2. in the shader change the following lines



to



With those two changes your shader seems to work perfectly.
Serial Velocity
15
Years of Service
User Offline
Joined: 24th Aug 2008
Location:
Posted: 13th Apr 2009 23:06 Edited at: 13th Apr 2009 23:09
@Green Gandalf

Thanks alot! The shader works flawlessly as you said, here it is if anyone wants to use it:



and heres a screenshot:


Attachments

Login to view attachments
jason p sage
16
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 13th Apr 2009 23:08
Serial Velocity
15
Years of Service
User Offline
Joined: 24th Aug 2008
Location:
Posted: 13th Apr 2009 23:10
Quote: "Can you get some "yellowish" city lights going?"


You can get any texture from showing up as night lights, just replace the "Night.png" texture with anything you like

AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 14th Apr 2009 17:49
Oh LOL i kept refreshing the page and didn't even realize the thread had a new page X_X

Here is the project again. This (terrain.fx) shader does what I want except for the seams ofc. I've tried so many combinations that I don't really know what else to do. Besides the fact that i've had to up the version to 3.0 to be able to compile it.
You'll find in the shader the following lines
Quote: "// Either of these next 2 lines cause problems when compiled as PS2.a
// Out.colour = baseColour;
Out.colour = (baseColour * (ambiColor + diffuse*LM) + specular*LM);
"

Just change the shader to compile to 2.a and it probably won't. The problem i had that wjhen it did compile it had an overly metalic shine has gone away without any meddling from my part except for a reboot

Take care
AtomR

Attachments

Login to view attachments
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 14th Apr 2009 20:56 Edited at: 14th Apr 2009 21:00
Quote: "Oh LOL i kept refreshing the page and didn't even realize the thread had a new page X_X"


You are not alone.

Just had some fun playing with your shader. The problem is beginning to look like an instruction count issue. I tried commenting out a line and replacing it with something simple, for example,



compiles and runs in DarkShader. This working version is reported as using approximately ( ) 91 instruction slots - the limit for PS2a is 96. I've experienced weird messages before when I get near the limit - it's as if the compiler gets confused.

You could try carefully examining your code to see if you can reduce the instruction count (start with a version which DOES work first so you can see what effect your changes have ). However, my experience is that that task is difficult because of the optimisations already carried out by the shader compiler.

I can't test PS3 till I get my new PC.

Edit The sort of optimisations I have in mind are to replace things like



with



(and consequential changes). But my guess is that the compiler does that anyway.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 14th Apr 2009 22:22 Edited at: 15th Apr 2009 14:43
[edit]


What an erratic behaviour this has. This shader, according to FX Composer, has around 67 instructions on the pixel shader. But it won't compile on DBP (compiles fine on FXC).
So I've officially upped the version of this shader to 3.0 coz it compiles fine as 3.0.

Is it possible that a faulty graphics cards is responsible for a shader not compiling properly?

Take care
AtomR
mr Handy
16
Years of Service
User Offline
Joined: 7th Sep 2007
Location: out of TGC
Posted: 21st Apr 2009 09:21
1. try { texture = <cubeTexture>; instead of { texture = (cubeTexture);

2. try NOT to compile 2_a but 2_0 as it has better compatibility.

3. Maybe camera position vector is not supported in db

A door is a door is a door. Even a swinging one. I always wanted to take part in my life. Here, have a piece of gum. I've played Gulman 3D part 2!
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 21st Apr 2009 13:59
AtomR

Only just realised you've edited your post.

Anyway, I see what you mean.

Quote: "Is it possible that a faulty graphics cards is responsible for a shader not compiling properly?"


I suppose that's possible - but I very much doubt that is the problem in this case.

I've just tested your new version of the shader and it doesn't compile in DarkShader - but does in FX Composer. However, FX Composer seems to be giving a warning message (although it doesn't flag it as one) and I do know that DarkShader doesn't handle warning error messages correctly - it treats them as fatal errors so the reason the shader doesn't compile could be down to that. However, that still doesn't explain why the two programs give different error messages.

I've now had a closer look at your code, prompted by the message from FX Composer which says:

Quote: "SetKey passed unmatched type (etc)"


I think this may be because you've mixed up the lengths of the Cam variable. I believe this should be declared as a float3 with consequential changes elsewhere in the code (I admit I'm not sure about this and DBPro may fill in the final "1" for you - however, I do know for certain that float3's work). For example, the following line could be causing problems:



if the fourth element of "Cam" is not defined by the application.

Also, since temp is a float3 whereas Cam and In.pos are float4 (i.e. a "vector"?) you might get a warning message. It's probably safer to add in the "swizzles" explicitly to make the intention clear to the compiler, e.g.



It may be worth checking the rest of your code to see if there are any related ambiguities or possibly incompletely defined constants.

Actually, I've just made those two changes, i.e. declare Cam as float3 and add the swizzles just described and the shader compiles fine in both DarkShader and FX Composer. However that is not the whole story as your earlier shader still doesn't want to compile in DarkShader or FX Composer with those changes. That may be the instruction count problem mentioned earlier (but I'm not now sure ).

I'll have another look at this when I get a bit more time.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 21st Apr 2009 16:32 Edited at: 21st Apr 2009 16:33
Mr.Handy
Quote: "1. try { texture = <cubeTexture>; instead of { texture = (cubeTexture);

2. try NOT to compile 2_a but 2_0 as it has better compatibility.

3. Maybe camera position vector is not supported in db"


The thing is that both the camera position vector and the (cubeTexture) has already compiled as 2_0, 2_a and 3_0. So it is definatelly compatible with DBP.

GG
Quote: "Only just realised you've edited your post. "

No problem. I figured you are just getting settled with your new computer and to tell the truth I haven't even looked at shaders in a few days. It's erratic behaviour is confusing and enraging me. When u said that maybe it was the instruction count I decided to remove one texture layer to reduce the number of instructions and it did compile. So i changed nothing else and left my computer on during the night (as I always do) and the next day, first thing in the morning, I ran the exact same code with the exact same shader and it no longer compiled. That's how erratic it behaves. I reduced the instruction count to as little as 45 and it didn't compile.

Quote: "I've now had a closer look at your code, prompted by the message from FX Composer which says:

Quote: "SetKey passed unmatched type (etc)""

Weird that my FXComposer doesn't give any message.

I'll try now the changes both of you suggested.

Take care
AtomR
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 21st Apr 2009 17:32 Edited at: 21st Apr 2009 18:06
I took a step back and picked up my backup of the shader when I was only using the command texCube to sample the cube map. It compiles perfectly as 2_a and 3_0. It doesn't compile as 2_0 because it exceeds the instruction limit (both DBP and FXComposer say so). FXComposer reports the shader as having
// approximately 59 instruction slots used (15 texture, 44 arithmetic)



Next step, I only alter the first texCUBE(cubeSample, UVW1); instruction with a texCUBEgrad(cubeSample,UVW1,ddx(UVW1),ddy(UVW1));
The shader still compiles as 2_a and 3_0; FXC reports it as having
// approximately 68 instruction slots used (15 texture, 53 arithmetic)



So i then alter the next texCUBE with a texCUBEgrad instruction (plus its ddx/ddy components) and it no longer compiles as 2_a. It it only compiles as 3_0. FXC reports it has having
// approximately 76 instruction slots used (15 texture, 61 arithmetic)



So, regardless of what DBP, FXC and DarkShader report its most definatelly a instruction count problem and I have decided to "upgrade" the shader to 3_0 as it will not work as any previous shader model.
Agreed?

So here is the "final" version of the shader

GG, when u finally get your new computer that allows you to play around with shader model 3 can u help me get rid of those nasty seams? I haven't been sucessfull at all in removing them Did u get around to doing the 16 texture+normal + roads you said you'd try to?

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 21st Apr 2009 20:30
Quote: "I figured you are just getting settled with your new computer "


Still waiting unfortunately.

Quote: "Weird that my FXComposer doesn't give any message."


Which version are you using? I'm still using FX Composer 1.8, i.e. 1.8.815.850.

Quote: "So, regardless of what DBP, FXC and DarkShader report its most definatelly a instruction count problem and I have decided to "upgrade" the shader to 3_0 as it will not work as any previous shader model.
Agreed?
"


That seems to be the most likely explanation now that we've corrected the other problems - but I'm not 100% convinced.

Quote: "GG, when u finally get your new computer that allows you to play around with shader model 3 can u help me get rid of those nasty seams? I haven't been sucessfull at all in removing them"


I'll certainly have a go at it.

Quote: "Did u get around to doing the 16 texture+normal + roads you said you'd try to?"


Not yet - but I think all the necessary ingredients are in place. I just need some time to work on it carefully.

The list of tasks seems to have grown recently.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 21st Apr 2009 22:49
Quote: "Which version are you using? I'm still using FX Composer 1.8, i.e. 1.8.815.850."

I have 2.51.0827.1525. Maybe this version compiles on the first successfull shader model it finds. I.e. when it can't compile as 2_a automatically goes to 3_0. Although that would be a bit counter productive in case u actually want a shader aimed at a particular shader model.


I'm taking a break from this shader for now. I think I've done all that I can and am going to focus on coding other important aspects of my game, like an actual game engine for instance eheh.

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 21st Apr 2009 23:02
Quote: "I'm taking a break from this shader for now."


Good idea. If I recall correctly this was just an experimental shader to see if you could use cube maps as a source of several images. The answer seems to be "yes" but it isn't easy to get the details right.

The other method (which I have yet to finalise) is to use a single texture/image as a "texture atlas". I'm sure that will be simpler in the long run.

Quote: "I have 2.51.0827.1525."


When I get my new PC I'm going to upgrade to the latest version of FX Composer. It would have been difficult or impossible on my present machine.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 22nd Apr 2009 13:04 Edited at: 22nd Apr 2009 13:14
Quote: "The other method (which I have yet to finalise) is to use a single texture/image as a "texture atlas". I'm sure that will be simpler in the long run."

Oh you'd be surprised :/ It's equally complicated (impossible?) to get rid of seams and the seams are much much more noticeable at the distance even using tex2Dgrad. So I scratched that method from the table.
Here is my attempt at it. Simple shader that uses one bitmap will all 6 textures, no bump mapping no shadow mapping etc for simplicity.

Quote: "Good idea. If I recall correctly this was just an experimental shader to see if you could use cube maps as a source of several images. The answer seems to be "yes" but it isn't easy to get the details right."

Yeah, it is experimental and a learning experience but it is also "research" for what method I will be using on my game. So I'm not quite done with it yet. I shall prevail

Take care
AtomR

Attachments

Login to view attachments
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 22nd Apr 2009 22:10
Quote: "Oh you'd be surprised :/ It's equally complicated (impossible?) to get rid of seams and the seams are much much more noticeable"


I certainly will be surprised - because the method I'm using gets rid of the seams. I just haven't got around to applying it to the 4x4 texture atlas yet.

Perhaps I will after all be surprised.

Or perhaps you will be.

I'll look at this later. Cooking supper at the moment.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 23rd Apr 2009 00:47
I hope I'm the one that gets surprised

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 23rd Apr 2009 14:20 Edited at: 23rd Apr 2009 15:00
Quote: "I hope I'm the one that gets surprised"


If I'm right you shouldn't be.

I haven't checked your demo in detail, but I did look at your main image ("base.dds"?). I suspect that you've forgotten to give each image a border consisting of copies of the appropriate parts of the image.

A quick check suggests each of the six component images is seamless - whereas they shouldn't be (except by chance). Only the central part that you are trying to sample should be seamless - this should be surrounded by copies of the relevant parts of the same image. This allows the shader sampler to use the correctly coloured pixels when it filters the samples the edges of the area you are trying to use. The following image illustrates what I mean:



The central blue region represents the seamless sub-image you are trying to use. The red, green and yellow regions represent the appropiate parts of the same image as if the blue image had been tiled.

I thought you had already done this since we discussed that several posts ago. The reason for using the texgrad instruction was to stop the GFX card from using the wrong mipmaps when it reads over the edge of the blue area. (Thanks due to Paul Johnston for identifying this as the problem - and for providing a simple solution.)

It sounds as if I need to post that demo sooner rather than later.

And perhaps a few words of explanation would be useful too.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 23rd Apr 2009 14:46 Edited at: 23rd Apr 2009 16:21
Hmm I didn't forget to give the border. I thought that that border was just one attempt at getting rid of the seam back when we thought that the seam was caused by sampling from the neighbour image, way before we(by we I mean you and Paul ) even thought of using tex2Dgrad. Now that we "know" the seam is caused by sampling from the wrong mipmap level I assumed we wouldn't need the border.

Quote: "A quick check suggests each of the six component images is seamless - whereas they shouldn't be (except by chance)."

Why? All of the six textures are to be repeated over the area where their respective mask color covers the terrain.
Ah ok I was misunderstanding what you were saying. You are saying they should be seamless textures but with an added border repeating the last pixels on each side to prevent the sampling of neighbour textures.
How many pixel do u think the borderr should be? 1 pixel is enough or would I need more. Anyways, I'll try that this afternoon after lunch.

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 23rd Apr 2009 14:59
Quote: "Ah ok I was misunderstanding what you were saying. You are saying they should be seamless textures but with an added border repeating the last pixels on each side to prevent the sampling of neighbour textures."


Exactly.

Quote: "How many pixel do u think the borderr should be? 1 pixel is enough or would I need more."


You will need several because of the mipmaps. Each mipmap will halve the number of pixels, so if your border is 16 pixels wide the first mipmap reduces that to 8, the next to 4 and so on. In other words you may still get seams - but only when the object is a long way away from the camera in which case it might not matter. May need to experiment with this a bit - one reason holding up my demo, just haven't had time to check all the details.

It may be possible to use the tex2DGrad function to limit the maximum mipmap that is used - but that solution might be worse than having distant seams.

I think I need to produce that demo soon.

[Strange, Browse button working now - here's the image.]

Attachments

Login to view attachments
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 23rd Apr 2009 17:18 Edited at: 23rd Apr 2009 18:14
Here is a low res of the texture I just altered. 16 px on each side of each texture. Now I need to rescale the UVs of the object to 88.89% of its original uv, correct?

http://forum.thegamecreators.com/xt/xt_apollo_pic.php?i=1740428

[edit]
Pardon my schepticism but I still don't believe that this is the problem. Because in this particular case the textures are side by side and the top and bottom sides of the texture don't have neighbors but the seams appear :/ The top and bottom sides are being wrapped by default right? Well no point speculating. Better put my hands to the job and see for myself.

[edit2]
ARGHH!!! I am suposed to be taking a break from this but here I am being driven insane again


Here is what I did. I only tried it on the V component of the UV coordintes because its simpler and if i can remove the seam on that side I can do it on the other.
My original texture is 256*256, I added 32pixels (16 on each side = 288*288) which means that the true texture is only 88.89% of the bitmap.

((Temp_UV.y)*temp)+.056 means that I scale the UV.v by 88.89% (temp=.8889) and then offset it by 16 pixels that in UV range equals to .056 according to my calculations. The seams is still there X_X

[Replaced the low res texture with the full res texture in case anyone wants to test the shader.]

Take care
AtomR

Attachments

Login to view attachments
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 23rd Apr 2009 18:02 Edited at: 23rd Apr 2009 18:06
And here is the screenshot showing the seam


Take care
AtomR

Attachments

Login to view attachments
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 23rd Apr 2009 20:03 Edited at: 23rd Apr 2009 20:05
You need to use the scaled UV coords without the frac when calculating the ddx and ddy values.

The problem seems to be that the hardware looks at the changes in the UV values when deciding on which mipmap to use. The use of frac results in a big jump in object UV values for neighbouring screen pixels so the hardware thinks the object is a long way away and uses a higher mipmap. You can stop this by using a smooth version of the UV coords in the ddx and ddy calls - i.e. without the fracs. You DO need the fracs of course for the UV coords themselves. The difference between tex2D and tex2DGrad is that tex2D uses the UV coords for the texture lookup AND for deciding which mipmap, whereas tex2DGrad uses the UV coords for the texture lookup and the derivative arguments for deciding which mipmap. Your code effectively reproduced the default behaviour by using the frac'd versions in the derivative arguments.

That's what I think is going on.

Edit Accidentally edited out the bit which said "I'll look at this tonight and post a simple demo - or a more interesting one if I have time."

Time I went home.
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 24th Apr 2009 01:23
Quote: "Accidentally edited out the bit which said "I'll look at this tonight and post a simple demo - or a more interesting one if I have time." "


Ok, got as far as cleaning up my existing demo and started to make the changes needed for a more useful demo. Hope to add to it later with a more interesting 4x4 texture atlas or similar.

The large green and red dots have been added to the images purely so you can see that the tiling is working correctly.

Anyway, this demo shows how one half of a texture can be used to tile an object seamlessly and contains four techniques:

filter1

This uses the original seamless images with the tex2DGrad function and linear filtering in the texture look-up - seams are visible at times (this may depend on the GFX card).

noFilter1

Same as the previous technique except no filtering is done. No seams are visible - but the textures don't look very nice and change strangely as you approach at an angle (because the mipmap used changes suddenly across the object).

filter2

This uses the embedded seamless images (i.e. with a border) with the tex2DGrad function and linear filtering in the texture look-up - I haven't noticed any seams with this technique and it is my preferred technique so far.

noFilter2

Same as the previous technique except no filtering is done. Looks very similar to technique noFilter1.

I've started to edit my preferred technique filter2 so it can accept an arbitrary texture atlas consisting of n x m sub-images with each containing an embedded seamless image. That's one reason why it's pixel shader code looks a little different from the others - but that difference is mainly cosmetic at the moment. It does, however, also contain a minor correction suggested by AtomR's code - if you run the demo and compare the different techniques from different camera positions and angles you should see that the preferred technique (filter2) looks noticeably better. I think this is partly because I've applied the ddx and ddy functions to both UV coords rather than x and y separately as done in the other techniques (thanks AtomR for making me realise this ).

Hope this answers some of your questions.

Attachments

Login to view attachments
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 24th Apr 2009 02:24 Edited at: 24th Apr 2009 02:26
I stand corrected and surprised
Unfortunatelly I just arrived home now (midnight) and after 1 month of lay off I have to go to work tomorrow of all days
So i'll take a real good look at your shader code tomorrow just as soon as i get home. Thank you GG.

Quote: "I think this is partly because I've applied the ddx and ddy functions to both UV coords rather than x and y separately as done in the other techniques (thanks AtomR for making me realise this )."

From what little I remember from Mathematical Analisys from the first year of college, for an equation with 2 variables a partial derivative was calculated for x (df/dx) by treating the x as a constant and for y (df/dy) by treating y as a constant. So i just thought I needed the two UV components to derive one in order of the other.

I hope that was clear coz I can't speak math mumbo jumbo in english very well. Hardly at all in portuguese let alone english.

Anyway i'm really anxious to try this method out but it'll have to wait to tomorrow night X_X

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 24th Apr 2009 11:20
Quote: "From what little I remember from Mathematical Analisys from the first year of college, for an equation with 2 variables a partial derivative was calculated for x (df/dx) by treating the x as a constant and for y (df/dy) by treating y as a constant. So i just thought I needed the two UV components to derive one in order of the other."


No (but yes they are both partial derivatives).

The reason is (probably ) that the card needs to know how both coords are changing in each direction. For example, if the object or camera is rotated slightly relative to the other then as you move across the screen both the U and V coords will change so the ddx() function needs to be applied to both of them to find out the overall rate of change. I guess the final mipmap value is some sort of combined compromise from the result of these two functions - I haven't been able to find any specific documentation on this yet, but it would be helpful when you take control of mipmapping yourself.

I look forward to hearing how you get on.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 24th Apr 2009 15:13
I was under theimpression I had tried every possible combination. I had:

float2 Temp_UV=frac(In.UV);

float2 UV1={Temp_UV.x/6, Temp_UV.y);

I had tried this:
float4 BaseMap=text2Dgrad(TexSample, UV1, ddx(UV1.x),ddy(UV1.y));

this:
float4 BaseMap=text2Dgrad(TexSample, UV1, ddx(Temp_UV.x),ddy(Temp_UV.y));

this:
float4 BaseMap=text2Dgrad(TexSample, UV1, ddx(Temp_UV),ddy(Temp_UV));

and this:
float4 BaseMap=text2Dgrad(TexSample, UV1, ddx(UV1),ddy(UV1));

but never this:
float4 BaseMap=text2Dgrad(TexSample, UV1, ddx(In.UV),ddy(In.UV));

X_X

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 24th Apr 2009 22:19
Quote: "but never this:
float4 BaseMap=text2Dgrad(TexSample, UV1, ddx(In.UV),ddy(In.UV));"


You should thank Paul Johnston for that - the only change I made to Paul's code was to apply both ddx() and ddy() to the vector In.UV instead of its components, and that change was prompted by your code.

More importantly, did it work?

When I get the full shader written it will include appropriate credits - I doubt anyone wants to be in the credits of an incomplete shader demo.

But I think we are making excellent progress.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 24th Apr 2009 23:13 Edited at: 25th Apr 2009 00:50
[deleted old post coz it was irrelevant]
What is invUVcopies for?
From what I can see its basically diving the U component by 2 and keeping the original V component. Any particular reason why you are doing that in the VShader? Or are u just trying not to waste instructions from the PShader?

this "Out.UV2 = In.UV * UVTiling * invUVCopies;"

equals having in the PShader

float2 Temp={In.UV.x/2,In.UV.y);
or even
float2 Temp=In.UV*invUVcopies;
correct?

I don't think we are making good progress at all. You are making good progress I am just trying to keep up with you

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 25th Apr 2009 12:17
Quote: "What is invUVcopies for?"


Answer:

Quote: "I've started to edit my preferred technique filter2 so it can accept an arbitrary texture atlas consisting of n x m sub-images with each containing an embedded seamless image. That's one reason why it's pixel shader code looks a little different from the others"


The idea is that you pass all fixed constants from the application (i.e. DBPro here) - it also adds greater flexibility. The "/2" is because my example used two sub-images.

Quote: "Any particular reason why you are doing that in the VShader?"


Yes. As a general rule, I never do anything in the pixel shader that can be done in the vertex shader. Any operation which linearly interpolates correctly when passed from the vertex shader to the pixel shader should be in the vertex shader. It is usually far more efficient to do calculations in the vertex shader than in the pixel shader. This is because objects typically have far more pixels on screen than vertices (not always true). A simple plain might have 6 vertices and a million pixels on screen. [Now that you've raised the question I realise that I'm not sure what the trade-off is between calculations in the pixel shader and linear interpolation of quantities passed from the vertex shader. I've always assumed that the hardware linear interpolation is done much more efficiently than the code we might put in the pixel shader. But that may be, after all, just an assumption on my part. Something else to check out. No wonder I never get as far as writing a game. ]

Quote: "Or are u just trying not to waste instructions from the PShader?"


That as well. It is very easy to exceed instruction count limits in the poixel shader - especially for PS2.

Quote: "this "Out.UV2 = In.UV * UVTiling * invUVCopies;"

equals having in the PShader

float2 Temp={In.UV.x/2,In.UV.y);
or even
float2 Temp=In.UV*invUVcopies;
correct?"


Yes. (But see my comments above.)

You still haven't told me whether it worked.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 25th Apr 2009 13:12
Oh I did tell you it didn't work but then I
Quote: "[deleted old post coz it was irrelevant]"

Apparently not all of it was irrelevant. Sorry.
BUT I was trying it on my cubemap version because I prefer that method. Overall I got better results with it then with the texture "atlas map". The seams at a distance are so so much more noticeable with the atlas map. I realise texCUBEgrad works differently (because of the whole 3 component UVW maybe) so I'll have to work with the atlas map. Yesterday I spent a lot of time studying your shader and striping it down to see what did what. I started by removing the uvtiling in the shader and instead altering the actual object UV's (within DBPRO) and then removed the invUVcopies and your shader still worked without seams. But the thing is, without the UVtilling and invUVcopies, the rest is exactly what I did so i think the [brilliant] way you setup your imbedded texture may be the trick that is missing from what i was doing. I was repeating the last pixels of each tech texture to add a border but you actually tiled the texture on that border.
But i see now what invUVcopies is doing and it make a lot of sense.

Quote: "I've always assumed that the hardware linear interpolation is done much more efficiently than the code we might put in the pixel shader. But that may be, after all, just an assumption on my part."

Quote: ""this "Out.UV2 = In.UV * UVTiling * invUVCopies;"

equals having in the PShader

float2 Temp={In.UV.x/2,In.UV.y);
or even
float2 Temp=In.UV*invUVcopies;
correct?""

I think you are right. The results are slightly diferent when using one or the other. The way you did it in the VShader gets much sharper results then adding the float2 Temp={In.UV.x/2,In.UV.y); in the PShader. The texture gets a lot more blured nearer to the camera this way.

Quote: "No wonder I never get as far as writing a game. "

True. I once (in the good old DBclassic days) managed to get 90% of a game completed (then lost all the work due to disk malfunction and not doing backups X_X) but it was so so boring after the engine was created. The parts where u make levels and test them and all that was really hard work. The interesting part is this part we're on now constantly trying to find new ways of doing really cool stuff
Of course I was hardcoding the levels block by block, brick by brick. I'm not making that mistake again. I got half a level editor made now for my next projects. I plan on releasing it when its in a decent state.

Keep up the good work

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 25th Apr 2009 13:47
From my post a few posts back:

Quote: "Edit Accidentally edited out the bit which said "I'll look at this tonight and post a simple demo - or a more interesting one if I have time." "


You said:

Quote: "Oh I did tell you it didn't work but then I

Quote: "[deleted old post coz it was irrelevant]"
Apparently not all of it was irrelevant. Sorry.
"


"History repeats itself, first as tragedy, then as farce."

AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 25th Apr 2009 14:58 Edited at: 25th Apr 2009 20:49
Revenge is a bitch

[EDIT]
Working great with the atlas version. I don't even get any seams in the distance.
I'm just trying to add the normal mapping and light mapping will post the shader ASAP.

Ok finished the shader and I don't know why the overly shiny terrain is back and i can't get rid of it this time :/

Can u look at it GG and see why its hapening?


Take care
AtomR

Attachments

Login to view attachments
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 25th Apr 2009 20:53 Edited at: 25th Apr 2009 20:54
Here is the atlas shader. I changed my atlas image from a 1x6 to 3x2 grid. Its no point having the u texcoord component divided by 6 and the v component in full. I think that allows for a lesser margin for error on the sampler part. I hope I'm making sense

Take care
AtomR

Attachments

Login to view attachments
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 26th Apr 2009 00:14 Edited at: 26th Apr 2009 00:15
Here's a screenshot of your demo using my old PC:



My much newer laptop just gives a bright red terrain - neither looks shiny as in your screenshot.

Attachments

Login to view attachments
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 26th Apr 2009 00:32
When I run the program that is the exact same image i get. Only when u move do u see how shiny everything is.

try placing the camera here:

position camera 1700,200,1080
yrotate camera 339

You'll be right in the middle of where everything is the shiniest.
When i ran this code and saw 24fps i actually wondered how much fps you'd get if i was getting such a low value. I bet you cannot wait for your new computer.
Weird thing is that I use the exact same code as in the cube map shader (your normal map code) and its not that shiny there.

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 26th Apr 2009 00:41
Quote: "Only when u move do u see how shiny everything is."


I couldn't wait that long.

OK, I'll adjust the settings for my PC and try it again.

However, you seem to be using some of my old bumpmapping code and Morcilla has, yesterday, pointed out a problem with it. See the following thread:

http://forum.thegamecreators.com/?m=forum_view&t=148754&b=1

I'll try that fix and see if it makes a difference.

Quote: "When i ran this code and saw 24fps i actually wondered how much fps you'd get if i was getting such a low value. I bet you cannot wait for your new computer."


The anticipation is killing me.
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 26th Apr 2009 01:15
I think you forgot to scale and bias your normal maps when you loaded them. I amended your FX code as follows (and re-normalized just in case):



Is that any better?
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 26th Apr 2009 10:57
LOL i just jumped from bed coz I dreamt that I forgot that
Its the copy paste syndrome back to bite me in the ass.

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 26th Apr 2009 11:17
Quote: "Its the copy paste syndrome back to bite me in the ass."


It can be worse than that believe me.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 26th Apr 2009 11:45
I experimented to see what values the ddx(In.UV2) assumes and after a bit of tinkering I added this

float DX=clamp(ddx(In.UV2),0,.005);
float DY=clamp(ddy(In.UV2),0,.005);

to prevent the use of very low mipmaps that show seams in the distance but my FPS droped to 11 Ouch

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 26th Apr 2009 12:50
Well done.

However, I think you should be using something like:

float DX=clamp(ddx(In.UV2),-0.005,.005);
float DY=clamp(ddy(In.UV2),-0.005,.005);

because the UV values could be decreasing rather than increasing, depending on the object's orientation to the camera.

I guess the values you should be using are related to the screen resolution as well.

Quote: "but my FPS droped to 11"


I wonder what mine would drop to?
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 26th Apr 2009 19:05 Edited at: 26th Apr 2009 19:10
Thanks GG! You are right, coz advanced terrains v coordinates are negative. At least they were in most AT i analized when me and VanB were trying to get them lightmapped with Darklights.

I get an average of 35fps with the shader.


Here is the final (?) shader. Quite happy with it. Not sure how usable it is at 35fps in my computer in an application with no A.I., no collision, no object no nothing but it does what I wanted it to do. 6 textures with Normal, specular, light mapping and we managed to keep it at shader model 2.a

However there is still something that eludes me a bit (a lot ) that I just copy pasted from your code and that is the 3d math calculations for the normal and specular mapping.

Quote: " float3 tempLightDir = normalize(In.Light);
float3 tempViewDir = normalize(In.View);
float diffuse = saturate(dot(normal, tempLightDir));
float3 reflect = 2 * diffuse * normal - tempLightDir;
float specular = diffuse * specLevel * pow(saturate(dot(reflect, tempViewDir)),specExpon);
"

Can u explain to me in layman's terms what each of these lines actually does. You know... talk to me like I'm four.

[edit]
Oh forgot to mention some changes I made to the shader. Since we are doing the UVtiling ourselves on the shader, I only use UV0 to calculate all other UVs. That way the users don't need to mess with vertex data on the DBPro side. They just need to alter the shader constant UVtilling.

Quote: "
Out.UV0 = In.UV0;
Out.UV1 = In.UV0 * UVtilling;
Out.UV2 = (In.UV0 * UVtilling) / tex_num;
"


Other then that no other big changes were made that I can think of.

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 26th Apr 2009 22:58
Quote: "You are right, coz advanced terrains v coordinates are negative."


That's not the issue. The ddx and ddy functions calculate the rate of change in the screen x and y directions. If the object is oriented to the screen so that U=0 is on the left and U=1 is on the right then ddx(U) will be positive. If the object is rotated so that U=0 is on the right and U=1 is on the left then ddx(U) will be negative - but, other things being equal, the same mipmap should be used.

Quote: "Here is the final (?) shader."


Looking good.

I would probably use the Mask images differently but that is your choice. Do you really need the specular lighting for a terrain? You might be able to remove that without much loss. Your choice again.

Quote: "Oh forgot to mention some changes I made to the shader. Since we are doing the UVtiling ourselves on the shader, I only use UV0 to calculate all other UVs."


That's what I would do too.

Quote: "Can u explain to me in layman's terms what each of these lines actually does. You know... talk to me like I'm four."


Sounds like a challenge. I'll post back later with an explanation.
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 27th Apr 2009 00:50
Quote: "However there is still something that eludes me a bit (a lot ) that I just copy pasted from your code and that is the 3d math calculations for the normal and specular mapping.


Quote: " float3 tempLightDir = normalize(In.Light);
float3 tempViewDir = normalize(In.View);
float diffuse = saturate(dot(normal, tempLightDir));
float3 reflect = 2 * diffuse * normal - tempLightDir;
float specular = diffuse * specLevel * pow(saturate(dot(reflect, tempViewDir)),specExpon);
"
Can u explain to me in layman's terms what each of these lines actually does. You know... talk to me like I'm four."


I'm assuming you are a mathematically literate four year old - but only just, so I've omitted lots of details.

Here goes anyway:


The first line normalizes the light direction vector, i.e. makes it have length 1.
This is a standard convention for any direction vector - especially those which are going to be used in lighting calculations. The light direction vector is actually the direction of the light viewed from the pixel we are trying to render, i.e. it points towards the light.

The second line does the same thing to the view direction vector. This vector represents the direction of the camera viewed from the same pixel as before, i.e. it points towards the camera.

The third line calculates the contribution of the light falling on the surface at the current pixel. If the surface normal and the light direction vector are pointing in the same direction, i.e. are equal after being normalised, then the light contribution is at its maximum of one. If these two directions are at right angles to each other then the light contribution is zero. The contribution of the light is calculated using a vector scalar product or "dot product", it is calculated as follows:

dot(normal, tempLightDir) = normal.r * tempLightDir.r + normal.g * tempLightDir.g + normal.b * tempLightDir.b

The "saturate" function limits the result of the calculation to the range 0 to 1, i.e. negative values get "clamped" to zero. This is necessary to stop negative values from giving strange lighting results in some circumstances.

The fourth line calculates the direction of the light as it is reflected from the surface at the current pixel, i.e. the direction of the reflected light. This is used in the specular calculation.

The fifth line calculates the overall strength of the reflected light at the current pixel from the point of view of the camera. This will be a maximum when the camera is in the same direction as the reflected light, i.e. when dot(reflect, tempViewDir) = 1. The variable specLevel represents the overall reflectivity of the surface - a value of zero means no reflectivity, whereas high positive values make the surface reflective and appear shiny or wet. Specular maps are used to modify this value. The pow command makes the effect of the specular contribution more concentrated around its maximum. For a hard shiny surface like glass or polished metal you would want a high power, e.g. specExpon = 30. For a softer, more diffuse, specular reflection you would want a lower power, e.g. specExpon = 5 say (you would probably also want to reduce specLevel as well). The final diffuse term at the beginning of the expression is a hack of mine ( ) to reduce the unwanted specular reflections you can get on surfaces which are facing away from the light.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 27th Apr 2009 00:53
How would you use the masks?

I removed the specular lighting and at first glance it seems I gained an extra 5 fps which is not bad at all and with literally no loss.

Because I limited the minimum mipmap it uses there is slight gliter at the distance. Funny thing is I've been playing Lost Oddysey (for the last 9 months ) on my brother's XBox360 and I keep complaining how it's unexcusable that a next gen system like that allows so much sparkling at the distance. Now I see that maybe it's because they have to choose the lesser of two evils like us lesser coders

Take care
AtomR
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 27th Apr 2009 01:16
Quote: "How would you use the masks?"


Like this: (I've commented out the specular bits plus a few other things that are not used.)



The above code assumes that the sums of the RGB components always add to 1 so they give the relative importance of each texture, i.e. for each pixel position on the terrain:

Mask1.r + Mask1.g + Mask1.b + Mask2.r + Mask2.g + Mask2.b = 1

Your code does something different. Try putting each Mask component equal to 1/6 for example, i.e. RGB = (42,42,42) (approx).

Quote: "and I keep complaining how it's unexcusable that a next gen system like that allows so much sparkling at the distance. Now I see that maybe it's because they have to choose the lesser of two evils like us lesser coders"


Quite possibly.
AtomR
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Portugal
Posted: 27th Apr 2009 17:41 Edited at: 27th Apr 2009 18:59
Nice, up to 65fps now. This may actually run on your computer

[edit]
Oh no no no! Actually that doesn't work at all. I either get a fully black terrain or the whole terrain textured with one single texture. But this problem only happens on DBP.
So I decided to get the shader on FXComposer. It works there strangelly. But a lot of problems are noticeable. I think it would be hell use to make a decent looking terrain.
Look at the pic.

Left is using the lerp, and right is using the "color weights". For one the color weights are additive. If u have a full red (by full red I mean the maximum red possible = 1/6th of full red) on mask 1 and the same on mask 2 they will show partial textures from each layer BUT will also be brighter like there is light there.


[edit2]
OR i totally misunderstood what u meant and you will soon prove me wrong

Take care
AtomR

Attachments

Login to view attachments

Login to post a reply

Server time is: 2024-05-17 09:33:52
Your offset time is: 2024-05-17 09:33:52