Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

Yours3!f

Member Since 04 Feb 2011
Offline Last Active Today, 01:23 AM
-----

#5018224 need help with shadow mapping

Posted by Yours3!f on 06 January 2013 - 10:17 AM

ok, I think I got it.

I just needed to transform the clip space shadow coords to ndc, then to tex coords.

 

#version 330 core

layout(binding=0) uniform sampler2D texture0;
uniform vec3 light_pos, spot_dir;
uniform float radius, spot_exponent, spot_cos_cutoff;

in vec3 normal;
in vec3 vs_pos;
in vec4 ls_pos;

out vec4 color;

void main()
{
	vec3 n = normal;
	vec3 l = light_pos - vs_pos;
	float d = length(l);
	l = normalize(l);
	float att = (1 + d / radius);
	att = 1.0 / ( att * att );
	float n_dot_l = dot(n, l);
	
	if(n_dot_l > 0)
	{		
		vec3 h = 0.5 * (l + normalize(-vs_pos));
		float n_dot_h = max(dot(n, h), 0);
		
		float spot_effect = dot(-l, spot_dir);
		if(spot_effect > spot_cos_cutoff)
		{
			spot_effect = pow( spot_effect, spot_exponent );
			att = spot_effect / att + 1;
		}
		att -= 1;
		
		vec4 shadow_coord = ls_pos / ls_pos.w; //convert to ndc
		shadow_coord = shadow_coord * 0.5 + 0.5; //scale, bias to [0...1]
		
		float depth = texture( texture0, shadow_coord.xy ).x;
		
		att *= depth < shadow_coord.z - 0.005 ? 0 : 1; //add bias to get rid of shadow acne
		
		color += vec4(vec3((0.1 + n_dot_l + pow(n_dot_h, 20)) * att), 1);
	}
	
	color.xyz = pow(color.xyz, vec3(1/2.2));
    //color = vec4(1);
}



#5017557 I need help understanding ARB_instanced_arrays.

Posted by Yours3!f on 04 January 2013 - 05:27 PM

drawing:

 

this allows you to draw 4 models, each with different transformation matrix

glBindVertexArray( vao ); //bind vertex array object that contains all the vbos etc... as usual

glDrawArraysInstanced(GL_TRIANGLES, 0, num_of_polygons * 3, 4);

 

again I didnt test it.




#5017548 I need help understanding ARB_instanced_arrays.

Posted by Yours3!f on 04 January 2013 - 05:07 PM

GLuint vbo; //vertex buffer object containing the matrices
glGenBuffers( 1, &vbo ); //create the vbo

// I get the feeling that this line is the key. It is all important and it has the least amount of information available.
glBindBuffer(GL_ARRAY_BUFFER, vbo); //bind it

mat4 matrices[4];

/*
fill matrices here...
*/

//fill the vbo with data
glBufferData( GL_ARRAY_BUFFER, sizeof( float ) * 16 * 4, &matrices[0][0], GL_STATIC_DRAW );

//now that the matrices are on the GPU, lets go ahead and use them

//get the position of the vertex attribute to access the vbo
int pos = glGetAttribLocation(shader_instancedarrays.program, "transformmatrix");
int pos1 = pos + 0; // <- According to mhagain, this gets the first row of the matrix specified in "transformmatrix".
int pos2 = pos + 1; // ... second row...
int pos3 = pos + 2; // ... third row...
int pos4 = pos + 3; // ... fourth row
glEnableVertexAttribArray(pos1);
glEnableVertexAttribArray(pos2);
glEnableVertexAttribArray(pos3);
glEnableVertexAttribArray(pos4); 
// Now I am really confused. If I understand what mhagain wrote, each of these specify one row of a matrix.
// BUT...
// Each is setting the stride to be 16 floats! Is this a typo? What is happening here? 

//set up the strides so that each vertex attribute location will point to each of the matrices.
//ie. pos1 --> matrices[0]
//pos2 --> matrices[1] etc...
glVertexAttribPointer(pos1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(0));
glVertexAttribPointer(pos2, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 4));
glVertexAttribPointer(pos3, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 8));
glVertexAttribPointer(pos4, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 12)); 

// This part I get...
glVertexAttribDivisor(pos1, 1);
glVertexAttribDivisor(pos2, 1);
glVertexAttribDivisor(pos3, 1);
glVertexAttribDivisor(pos4, 1);

I think this should work... haven't tested it though.

EDIT:
stride
Specifies the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in the array. The initial value is 0.
this tells the api how big each data pack (each matrix) is

pointer
Specifies an offset of the first component of the first generic vertex attribute in the array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target. The initial value is 0.
ie this tells the api where each matrix is located in the vbo


#5017312 I need help understanding ARB_instanced_arrays.

Posted by Yours3!f on 03 January 2013 - 06:08 PM

From the lack of views, posts and Google results, I get the feeling this is a taboo topic... Like talking about God in the Lounge... dry.png biggrin.png

I'm pretty sure it's not a taboo topic. The issue might be that this extension is designed to deliver good rendering performance, when rendering the same object like million times, with different transformation matrices. Therefore it is only used in huge projects, where it is needed (ie. games, and there aren't many OpenGL games).

I guess people who needed it got it right over time, and nobody made a decent tutorial.

Despite doing advanced stuff (mostly post-processing) I still haven't done this. Plus usually, when you get there to use this extension you already have a scene graph set up, etc.

 

But here's one of the extensions you may need:

http://www.opengl.org/registry/specs/EXT/draw_instanced.txt

 

a tutorial:

http://ogldev.atspace.co.uk/www/tutorial33/tutorial33.html

 

plus you have the docs and the specs. Read all these, and I think you'll get it right :)




#5014678 Porting to OpenGL

Posted by Yours3!f on 27 December 2012 - 06:16 AM

Hello people.

 

I have a Direct3D 9.0 engine and I want to add an OpenGL renderer.

The engine uses deferred lighting with Shader model 3.0 and unfortunately isn't written in abstraction level in mind. I mean, it uses DirectX types, objects and D3DX calls all over the code. 

My questions are :

1. What OpenGL version I should implement ? OpenGL 2.x , 3.x, 4.0 ? I need a smooth transition and easy port, that matches Direct3D 9.0 functionality well.

 2. Should I use glew, glut, SDL , other stuff like that ? I will most probably want to port it to other platforms like Linux, Mac ? I don't want to mess with extensions so probably glew will be of help.

3. Should I use nVidia CG shader language in order to use my existing HLSL shader code directly, without rewriting them to GLSL ?

4. Is there a good sample source code, tutorials, articles that show basic deferred rendering with a modern  OpenGL way  ( version 3 ++) ?

5. I'm using D3DX library for common math stuff etc, is there a library for OpenGL that is to it, like D3DX is to Direct3D ?

 

I have a limited OpenGL experience from the past.

 

Thank you.

More questions to come.

 

hi,

 

opengl 2.1 matches dx9 functionality.

yes you should use glew and sdl (or sfml, if you prefer c++-ish solutions), but these are not mandatory, you can write your own.

well cg is another language right? so you would have to port to cg then... the question is, do you want to learn glsl or not?

see: http://ogldev.atspace.co.uk/

but there are tons of others. google is your friend.

well for mesh loading and stuff related to that, you have assimp

for texture loading, you can do this with sdl / sfml. Just load in an image using sdl / sfml, acquire the pointer to the raw data, and fill a texture using that data.

for maths, you have tons of choices. The most popular ones are CML (http://cmldev.net) and GLM (http://glm.g-truc.net/).

I have also developed a math library: https://github.com/Yours3lf/libmymath

 

if you need anythin else, just go to the topics (http://www.gamedev.net/forum/25-opengl/) look at the right side of the page -->

and there you have it, tons of links.




#5011208 Bottom Row of 4x4 Matrix

Posted by Yours3!f on 16 December 2012 - 03:03 AM

well first take a look at this:
http://www.songho.ca/opengl/gl_transform.html
(the other pages are very useful too!!! so look around)

I'm not really sure if A is used at all, I did this a long time ago, but B is supposed to be the perspective divide element.
Or at least B and the projection matrix modify the 4th element of the position, so that in clip space if you divide by it, you get the ndc coordinates.
like when you do the transformations:
-Model (world) space (apply T here):
   model_space_pos = model_mat * vertex
-View (camera) space (apply R here):
   view_space_pos = view_mat * model_space_pos
-Clip space (apply projection matrix here):
   clip_space_pos = projection_mat * view_space_pos
-normalized device coordinates (do the perspective divide, apply B here):
   ndc_pos = clip_space_pos.xyz / clip_space_pos.w
-viewport coordinates (scale & bias to get texture coordinates, scale by window coordinates)
   viewport_pos = (ndc_pos.xy * 0.5 + 0.5) * vec2( screen_width, screen_height )

and to the other questions:
you would apply the 4x4 matrix to a 4 component vector (ie vec4)
and you would invert A and B by inverting the 4x4 matrix.


#5007062 is gdebugger wrong or do I really have 300gb in renderbuffers?

Posted by Yours3!f on 04 December 2012 - 07:18 AM

Hi,

I get false values too, I use a 1024x1024 RGBA8 cubemap texture. This should take:
1024 (width) x 1024 (height) x 6 (sides) x 4 (bytes per pixel) ~ 25 MB
instead it says 148 MB... So it is definitely wrong.
As far as I've seen it, it report correct values for 2D textures, but false ones for pretty much everything else.


#5006236 Blur shader (2 passes)

Posted by Yours3!f on 02 December 2012 - 02:33 AM

I'm learning how to use GLSL shaders at the moment. I'm implementing a Gaussian blur shader which uses 2 passes, one for horizontal and one for vertical blur.
My question is, do I need to create a texture target for each pass? This way I would render the scene to the first texture, then I would render the first texture to the second texture using the horizontal blur shader, and finally render the second texture to the screen using the vertical shader. I'm not sure if this is the right way.
The second possibility I have is to render the scene to the same texture two times once with each shader (and add a * 0.5 to the end of each shader). But with this solution, all the scene geometry has to be drawn twice (and not just 2D textures).

Is the double texture approach better? Is there another one?
Thank you!


This is how you do it:
-render the scene to a fbo #1 (ie to texture #1 attached to it).
-blur texture #1 using gaussian blur horizontally (or vertically) outputting to fbo #2 (ie to texture #2 attached to it)
-blur texture #2 outputting to fbo #3 (ie texture #1 that is attached to it)

You can see that I used 3 fbos and only 2 textures. This is because an fbo is just a concept, it only determines WHAT TO the gpu will output the pixels. The storage (which has megabytes of magnitude) is the texture attached to it.
But this "ping pong" rule applies to many other effects like depth of field etc. Where you need the same type of output texture, you can simply cleverly reuse the existing ones, thus saving gpu memory (which you can use later for storing additional assets).


#5005972 Non-Microsoft Market Share

Posted by Yours3!f on 01 December 2012 - 02:22 AM

macs have at most 5%, but you can only use OGL 3.x
linux based systems have at most 1%, and latest OGL

For cross platform development you need to use cross platform libraries, and build with non-cross platform IDEs and compilers. For cross platform libraries your best choice IMO would be SFML + OGL + GLEW (and other libs like freetype, freeimage, assimp etc. if needed)
For example I chose cmake to create both a makefile (so yeah gcc/g++) on Linux and a Visual Studio solution on Windows. As far as I know it works for mac too.
On linux your best choice is cmake and kdevelop IMO, but 100 developers will give you 100 answers to this question. You still have other IDEs like Eclipse and Qt Creator.
In my experience OGL has been enough for everything, so I don't see why you'd use DX even on Windows (why would you develop the same thing twice?).


#5005325 sky rendering

Posted by Yours3!f on 29 November 2012 - 09:16 AM

hi,

I'm trying to do sky rendering based on this: http://codeflow.org/entries/2011/apr/13/advanced-webgl-part-2-sky-rendering/

I got through most of the set up, I can now render to a cubemap, and display it, however I can't get the inverse view rotation matrix.
This is because I only worked with view-space, projection space so far. I tried to pass the inverse modelview matrix, but that didn't quite work out.
So my question is, is it possible to do this using view-space? If so how?

here's the shader I'm using:
#version 420 core

//uniform mat3 inv_view_rot;
uniform mat4 inv_proj;
uniform mat4 inv_modelview;
uniform vec3 lightdir, kr;
//vec3 kr = vec3(0.18867780436772762, 0.4978442963618773, 0.6616065586417131); // air
uniform float rayleigh_brightness, mie_brightness, spot_brightness, scatter_strength, rayleigh_strength, mie_strength;
uniform float rayleigh_collection_power, mie_collection_power, mie_distribution;
float surface_height = 0.99;
float range = 0.01;
float intensity = 1.8;
const int step_count = 16;

in cross_shader_data
{
  vec2 tex_coord;
} i;

out vec4 color;

//original
/*vec3 get_world_normal()
{
  vec2 frag_coord = gl_FragCoord.xy/viewport;
  frag_coord = (frag_coord-0.5)*2.0;
  vec4 device_normal = vec4(frag_coord, 0.0, 1.0);
  vec3 eye_normal = normalize((inv_proj * device_normal).xyz);
  vec3 world_normal = normalize(inv_view_rot*eye_normal);
  return world_normal;
}*/

//what i tried to do
vec3 get_world_normal()
{
vec4 device_coords = vec4(i.tex_coord * 2.0 - 1.0, 0, 0);
return normalize((inv_modelview * inv_proj * device_coords).xyz);
}

float atmospheric_depth(vec3 position, vec3 dir)
{
  float a = dot(dir, dir);
  float b = 2.0*dot(dir, position);
  float c = dot(position, position)-1.0;
  float det = b*b-4.0*a*c;
  float detSqrt = sqrt(det);
  float q = (-b - detSqrt)/2.0;
  float t1 = c/q;
  return t1;
}

float phase(float alpha, float g)
{
  float a = 3.0*(1.0-g*g);
  float b = 2.0*(2.0+g*g);
  float c = 1.0+alpha*alpha;
  float d = pow(1.0+g*g-2.0*g*alpha, 1.5);
  return (a/b)*(c/d);
}

float horizon_extinction(vec3 position, vec3 dir, float radius)
{
  float u = dot(dir, -position);
  if(u<0.0)
  {
    return 1.0;
  }
  vec3 near = position + u*dir;
  if(length(near) < radius)
  {
    return 0.0;
  }
  else
  {
    vec3 v2 = normalize(near)*radius - position;
    float diff = acos(dot(normalize(v2), dir));
    return smoothstep(0.0, 1.0, pow(diff*2.0, 3.0));
  }
}

vec3 absorb(float dist, vec3 color, float factor)
{
  return color-color*pow(kr, vec3(factor/dist));
}

void main(void)
{
  vec3 eyedir = get_world_normal();

  float alpha = dot(eyedir, lightdir);
  float rayleigh_factor = phase(alpha, -0.01)*rayleigh_brightness;
  float mie_factor = phase(alpha, mie_distribution)*mie_brightness;
  float spot = smoothstep(0.0, 15.0, phase(alpha, 0.9995))*spot_brightness;
  vec3 eye_position = vec3(0.0, surface_height, 0.0);
  float eye_depth = atmospheric_depth(eye_position, eyedir);
  float step_length = eye_depth/float(step_count);
  float eye_extinction = horizon_extinction(eye_position, eyedir, surface_height-0.15);

  vec3 rayleigh_collected = vec3(0.0, 0.0, 0.0);
  vec3 mie_collected = vec3(0.0, 0.0, 0.0);

  for(int i=0; i<step_count; i++)
  {
    float sample_distance = step_length*float(i);
    vec3 position = eye_position + eyedir*sample_distance;
    float extinction = horizon_extinction(position, lightdir, surface_height-0.35);
    float sample_depth = atmospheric_depth(position, lightdir);
    vec3 influx = absorb(sample_depth, vec3(intensity), scatter_strength)*extinction;
    rayleigh_collected += absorb(sample_distance, kr*influx, rayleigh_strength);
    mie_collected += absorb(sample_distance, influx, mie_strength);
  }

  rayleigh_collected = (rayleigh_collected*eye_extinction*pow(eye_depth, rayleigh_collection_power))/float(step_count);
  mie_collected = (mie_collected*eye_extinction*pow(eye_depth, mie_collection_power))/float(step_count);

  vec3 result = vec3(spot*mie_collected + mie_factor*mie_collected + rayleigh_factor*rayleigh_collected);
  color = vec4(result + vec3(0.1)/*just to make sure that I am writing to the cubemap*/, 1.0);
}


EDIT: it seems to work now. I just had to use the original, and pass inverse view matrix (it turned out to be the upper left 3x3 matrix of the modelview matrix), and I had to use the correct cameras (not the players camera, but turned to left, right up, do etc.).

Best regards,
Yours3lf


#5003809 driver bug?

Posted by Yours3!f on 24 November 2012 - 02:20 PM


It shouldn't crash under any circumstances, right?

Well... not necessarily. For example, if you give it a garbage pointer or size and cause it to commit an access violation, it's free to crash.

I'm not much of a video programmer, but here's my guess as to why it crashed: glTexImage2D requires you to pass a pointer to the texture data, and in your OP you're passing 0. If you read the docs for that function, it says "If target is GL_PROXY_TEXTURE_2D, GL_PROXY_TEXTURE_1D_ARRAY, GL_PROXY_TEXTURE_CUBE_MAP, or GL_PROXY_TEXTURE_RECTANGLE, no data is read from data." In the next paragraph, it says "If target is GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE or one of the GL_TEXTURE_CUBE_MAP targets, data is read from data..." (emphasis mine) This may explain why it crashes. I could be wrong, but that's my hunch.


well it is read if not 0 is passed.
"data may be a null pointer.
    In this case, texture memory is
    allocated to accommodate a texture of width width and height height.
    You can then download subtextures to initialize this
    texture memory.
    The image is undefined if the user tries to apply
    an uninitialized portion of the texture image to a primitive."

and that function didn't crash, but the fbo checker. And that function doesn't receive any pointer.


#5001214 picking in 2d

Posted by Yours3!f on 15 November 2012 - 07:29 AM

hello.
I implemented a simple 2d drawing sysytem that draws points and lines(for now)
I must implement a picking in 2d for intersection of a mouse click and a point and a line.
Has a sense create a ray for the intersection in 2d?
how i can implement these algorithm?
I also have to consider the modelview matrix and the scale/rotate that i can apply to the document .
there is an example?
thanks.


hey there, I don't really know how to deal with lines (approximate them as thin quads maybe?), but I've recently done this using triangles/quads:
http://www.gamedev.net/topic/633528-2d-picking-theory/

you might get an idea.


#4996807 uniforms

Posted by Yours3!f on 03 November 2012 - 03:16 AM

Why do you need this feature? If it is for the learning sake only, please wait until stable drivers release.
There are several sources of the problem.

What drivers are you using? GL_ARB_explicit_uniform_location is the part of GLSL 4.3 core spec, not 4.2. If you are using NV 310.xx drivers, then there could be a bug, since they are in a beta phase. If you are using previous releases, then you should check whether the extension is supported and probably enable it explicitly in GLSL (if it is supported).

I guess you don't have support GL_ARB_explicit_uniform_location and the reason it works for the first uniform is accidental correspondence with compiler's associated locations. NV uses alphabetical order of names. So, locations are as follows:
0 - mvp   
2 - texture0
1 - overlay_color

Before trying to use some new feature check if it is presented and read specification to understand how it works. ;)


:( I'm on AMD with only OGL4.2 drivers... I guess I'll have to stick with glGetUniformLocation...
as for the why: I just wanted to get rid of keeping track of uniform locations. It's not that cumbersome, but it would be great if I didn't have to.
I guess for the rest you're right, I just accidentally got the uniform locations right. Well, thank you for clarifying the situation. I just thought this was available since gl 3.1


#4990024 Using shaders vs fixed pipline

Posted by Yours3!f on 14 October 2012 - 06:51 AM

ok, thanks for all the replies.
I actually am working on the project for a pretty long time now, but switching still may be worth it.
So I decided to learn more about shaders and program two or three and probably I will stick with them.
"Master of my own lighting" sounds very good, but I´d rather like to focus on features for the gameplayPosted Image

Even if I don´t use it in this project in the end, I hope it at least will be worth the experience.


here's a cg implementation of the whole OpenGL fixed function pipeline. Cg is very similar to GLSL so you should have no problem porting it after you learned a bit of GLSL.
http://www.codesampler.com/source/ogl_cg_fixed_function.zip


#4989810 Using shaders vs fixed pipline

Posted by Yours3!f on 13 October 2012 - 10:33 AM

for each object you need to choose between rendering by shaders or fixed pipeline.
for example you can use shaders for the terrain, but render everything else using the fixed pipeline.
however shaders give you much greater flexibility, and new features (because of programmability).
generally it is only advisable to use fixed pipeline when the given hardware (and driver) can't handle shaders.

and yes, you need to reimplement the fixed function pipeline in the shaders if you want those effects (ie. lighting).




PARTNERS