Jump to content

  • Log In with Google      Sign In   
  • Create Account

14 years ago on June 15th Gamedev.net was first launched! We want to thank all of you for being part of our community and hope the best years are ahead of us. Happy birthday Gamedev.net!

tanzanite7

Member Since 20 Nov 2005
Offline Last Active Today, 03:51 AM
-----

#4969184 Vertex shader's failing to link...

Posted by tanzanite7 on 13 August 2012 - 02:21 PM

Erm, you forgot to tell what is the reported link error!

Code looks fine to me - bad drivers? Might confuse the driver with the no-op "rgba" swizzle/selector.


#4961970 Preprocessor on same line as code

Posted by tanzanite7 on 22 July 2012 - 11:38 AM

edit: damn, ninja post, this is in response to Daaark's post.

Don't know what OP had in mind, but i think you are missing the point.

It is NOT intended to be useful nor well readable etc. It is a challenge, bonus points if the code does something interesting. Check for example this (at the top of Ken Perlin's homepage).


#4953857 Water Style Direction

Posted by tanzanite7 on 29 June 2012 - 12:54 AM

A few thoughts:
* Use anisotropic filtering.
* Reflected sky is much brighter than the actual sky at/near horizon.
* Add a shimmer effect (in water plane direction at distance sample reflection with noise offset) - it is too clean reflection.

Use 3D texture for noise using z as time - for stable and pleasant shimmer.
Use more samples with noise offsets than one (diverging from one point outward in response to anisotropy and distance [ignore anisotropy at small distance - looks silly]).


#4951168 Random number problem!

Posted by tanzanite7 on 20 June 2012 - 06:20 PM

Posted Image:P


#4944183 Suggestion on reducing jaggies edge for particular angle.

Posted by tanzanite7 on 28 May 2012 - 06:25 PM

FXAA will not help with bad filtering. Are you using anisotropic filtering? ... if not then you definitely should as there is quite considerable anisotropy on the horizon.


#4940340 Terrain lighting

Posted by tanzanite7 on 15 May 2012 - 04:01 AM

By default a perspective correct linear interpolation is used - and that is what you want. Just do not forget to re-normalize the normals per fragment as interpolation obviously breaks it.

Last i had problems with normals i made a trivial geometry shade to send my geometry to, might be worth sharing (in case you have not used a geometry shader before):
// vertex shader
#version 330
precision highp float;
layout(location=0) in vec3 vxPos;
layout(location=1) in vec3 vxNormal;
layout(std140) uniform Transform { mat4 transform; } u; // some way to get your transform
out Position { vec4 position; } gs;
const float scale = 1.0; // for adjusting drawn normal length
void main() {
  gl_Position = u.transform * vec4(vxPos, 1.0);
  gs.position = u.transform * vec4(vxPos + vxNormal * scale, 1.0);
}
// geometry shader
#version 330
precision highp float;
layout(points) in;
in Position { vec4 position; } gs[1];
layout(line_strip, max_vertices=2) out;
void main() {
  gl_Position = gl_in[0].gl_Position; EmitVertex();
  gl_Position = gs[0].position;       EmitVertex();
}
// fragment shader
#version 330
precision highp float;
layout(location=0) out vec4 fbColor;
void main() {
  fbColor = vec4(1.0);
}

Just send another copy of your usual world geometry to this shader program to be drawn as GL_POINTS. Helps to ensure the normals are the way you assume they are and spot errors if not. Easier to see where the vertices are and hence judge what is interpolated with what etc.


#4934020 Problem: turning a bit shift into a division

Posted by tanzanite7 on 23 April 2012 - 03:24 AM

It would be interesting to compare the actual assembly that each of these produces, and see how clever modern optimisers are!

A bit OT, but got curious and ...

00000001400255A9  mov         eax,dword ptr [test1 (1400FA310h)]  
00000001400255AF  test        eax,eax  
00000001400255B1  jns         tester+28h (1400255B8h)  
00000001400255B3  add         eax,0FFFFFF01h  
00000001400255B8  cdq  
00000001400255B9  movzx       edx,dl  
00000001400255BC  add         eax,edx  
00000001400255BE  sar         eax,8  
00000001400255C1  mov         dword ptr [test1 (1400FA310h)],eax  
Very good imo (branchless instructions are an option also, but they usually perform much worse than branching code due to branch prediction and worse behavior with register-renaming hardware [or something i forgot {fucks up the dependency chain or something?}]). Expecting compiler to see through this code to just replace with a "sar" - would be too much to ask.

00000001400255C7  mov         eax,dword ptr [test2 (1400FA314h)]  
00000001400255CD  and         eax,0FFFFFF00h // if it would be clever then it would realize that this is actually unnecessary (compiler fails again because it assumes the next 3 instructions actually do something [it otherwise does keep track of this kind of bit manipulations and would remove the "and" - did test that])
00000001400255D2  cdq                 // this does absolutely nothing useful (it would be relatively easy for a compiler to deduce it based on previous instruction, but - evidently it does not)
00000001400255D3  movzx       edx,dl  //   --||--
00000001400255D6  add         eax,edx //   --||--
00000001400255D8  sar         eax,8   // this is actually all it should do
00000001400255DB  mov         dword ptr [test2 (1400FA314h)],eax  
Absolutely terrible. Like i said - one should avoid bit manipulations as compilers just can not see through it most of the time.

00000001400255E1  sar         dword ptr [test3 (1400FA318h)],8
Perfect. Not a fair comparision with 2. option tho as it rolled "load" and "save" also into the instruction - load / save should not be part of the test as in real case one could not roll them into one. So, the code should be seen as (for comparision purposes):
mov         eax,dword ptr [test3]  
sar         eax,8
mov         dword ptr [test3],eax  

edit: compiled with full optimizations with _ReadWriteBarrier separating the tests to ensure compiler does not mix the tests.


#4934005 Problem: turning a bit shift into a division

Posted by tanzanite7 on 23 April 2012 - 02:25 AM

Am i to understand that this is the intended result: -257/256 = -2, 257/256 = 1 ?

Exactly. That's how arithmetic bit shifting behaves.

The whole point of this is to get rid of bit trickery though.

(you replied before i realized i was talking crap)

At some point bit trickery must be used if a div instruction is to be avoided (either by you or the compiler) - there is no way around that. I assumed you had a problem with the unspecified behavior of ">>" (arithmetic vs not, although i have never encountered a compiler that used non-arithmetic for signed, but afaik it is allowed).

Confused what the actual goal here is :/ (ie. what goal is there for the replacement of the shift?)

edit:
This are the options (a far as i can see):
* val < 0 ? ((val - 255) / 256) : (val / 256) // performance is not a concern => no bit manipulations in source
* (val & ~255) / 256 // sacrificing a bit of performance to avoid ">>" ambiguity.
* val >> 8 // simple and fast, but relies on ">>" being arithmetic


#4931665 Holy grail of z-fighting - I thought I found it, why does it not work?

Posted by tanzanite7 on 16 April 2012 - 02:20 AM

Polygon offset is not a holy grail of z-fighting either and is not suitable for use as a general-purpose fix for this. Depth buffer non-linearity and the spec allowing implementation-specific differences mean that polygon offset sucks for this purpose...

I have to disagree, slightly. Drawing coplanar decals is pretty much exactly what it is there for. It is very well specified (especially for fixed-point depth buffers) - it is just that finding a good factor/unit pair can be maddening indeed.

Still, while it is not a silver bullet - i would say it is still pretty darn good. Especially as there really is no real alternatives to it.

I would recommend some rule-of-thumb for it:
* have a sane "near" (as far as you possible can. GL_DEPTH_CLAMP can help) and "far" (much less important than "near", but still as near as possible) distance.
* as high vertex offset (away from wall. not towards viewer) as one can get away with - to help with "factor" and ... well, everything really :) (ie. be as non-planar as possible).
* glPolygonOffset with ...
* as high an "unit" as one can get away with (based on zero-sloped wall/decal pair furthest from viewer). This is the easiest to choose - do it before starting to fiddle with "factor". While searching for a good value - look out for z-fighting with background-wall (=> "unit" too low, don't bother with values below 1.0) and z-fighting with foreground objects (=> "unit" too high).
* as low a "factor" as one can get away with (based on extremely steeply sloped wall/decal pair nearest to viewer) - this one is a pita. While searching for a good value - look out for z-fighting with background-wall (=> "factor" too low, higher "unit" also helps) and z-fighting with foreground objects (=> "factor" too high, higher "unit" also helps).



#4931368 OpenGL shader problem

Posted by tanzanite7 on 15 April 2012 - 12:37 AM

That is not after window creation, that is after "initRendering" :/.

If the offending "glCreateShader" is called anywhere in there then it would obviously guarantee a crash as without "initGlew" almost all of the gl* functions are pointing nowhere.


#4931323 OpenGL and Visual C++ (not a rehash)

Posted by tanzanite7 on 14 April 2012 - 08:19 PM

1) I didn't know GLUT was dead.
2) How do you suggest that I now go about learning GLEW? Do you recommend any tutorials?
Thank you for the quick and informative answer.

1) Went to refresh my memory when it last saw an update - surprisingly difficult to track down x_x. Definitely ~12 years ago tho, which given how much Gl has advanced since ... yeah, pretty dead (this does not mean that it does not work - it does work). freeGLUT is made to work very similarly afaik, so that should help on tutorial front. I have never used neither of thous - opting to create a gl context etc myself (probably not recommended as it creates a fairly major learning curve speed-pump at the very start).

Doing some OGL stuff goes roughly like this:
* get a window with a device context capable of accelerated opengl => freeGLUT helps you out there.
* initGlew() - to get the gl* function pointers to actually point to their implementations, if supported.
* create some message loop for the window in which you call your redraw function => freeGLUT helps you out there.
* in redraw function: do what you want Posted Image.
And that is pretty much it.

2) GLEW just loads all the extensions (The OpenGl version in Windows is locked down to 1.1 [1.2? can not remember exactly]] - so, pretty much everything needs to be loaded, including all the core functionality). GLEW does that all for you. It also provides boolean flags to check for non-core extensions (OGL 3.3 is powerful enough that you probably never even need any) - and if they return true then you can also use all of thous functions.

There really is nothing to learn there. It is needed just so that you could actually call the majority of the gl* functions.

A great tutorial for graphics in general (ie, not stuck in OGL 1.* mindset like the NeHe series), based on up to date (the internet tends to be riddled with horribly ancient stuff) opengl, is: http://www.arcsynthesis.org/gltut/
It also introduces the GLM library which is quite recommended.


#4931311 OpenGL shader problem

Posted by tanzanite7 on 14 April 2012 - 07:23 PM

glCreateShader needs to be loaded by glew ... where is your glewInit()? It must be called before you can call any of the newer functions like glCreateShader. Also, are you sure your GPU drivers support it (most likely supported with every non-ancient cards and non ancient drivers)?


#4931306 OpenGL and Visual C++ (not a rehash)

Posted by tanzanite7 on 14 April 2012 - 07:09 PM

Thought i give one possible setup example:
#define GLEW_STATIC
// adding the libs in source for convenience.
#pragma comment(lib,"opengl32.lib") // already present in VC
#pragma comment(lib,"glew_lib_file.lib") // lib needs to be in standard lib folders (32bit one in ".../VC/lib" and 64bit one in "../VC/lib/amd64").
// or use this trick:  __FILE__ "/../../../etc/path_to_somewhere_else/my_project_specific_copy_of_glew.lib"
#include "wherever_you_put_them/glew.h"
#include "wherever_you_put_them/wglew.h"
// or "#indluce <glew.h>" etc, if you drop them in "../VC/include"
bool initializeGLEW() {
	 GLenum err = glewInit();
	 return err == GLEW_OK;
}



#4931300 OpenGL and Visual C++ (not a rehash)

Posted by tanzanite7 on 14 April 2012 - 06:58 PM

1) Where should I get my OpenGL library?
2) Which libraries should I get (GLUT,GLU, GLAUX,etc...)?
3) Where should I put my library on my computer in order to reference it (w/ #include ...)?

1) You do not need to get anything (dll comes with every windows out of the box, relevant lib/h is included in VC)
2) GLUT is dead (might want to use freeGLUT instead), GLAUX was already dead when i first heard about Gl. GLU you might find useful, but is not strictly needed. As you are new, i would suggest GLEW as otherwise you will be stuck in ancient OpenGl (It is an extension loader).
3) It is up to you. I use a per project folder so i can choose per project which exact version i use of any given library.

Usage is very simple: http://glew.sourceforge.net/basic.html


#4927740 How many shader programs is too many?

Posted by tanzanite7 on 02 April 2012 - 08:38 PM

At what point should I start thinking about ways to consolidate shader programs?

When compilation time becomes an issue.

Ways to prevent it becoming an issue:
* don't load everything at once - stream it as much as possible. (ex: load immediately what is needed for the first scene and load the rest later. ex2: load the ones you expect will be needed while the user is navigating your menus to load/start a game).
* use binary blobs to cache already compiled programs.
* don't use so darn many shaders if you do not actually have to ;p.




PARTNERS