Discussion:
alpha in GLSL shader
(too old to reply)
Emanuel Berg
2013-10-18 23:55:54 UTC
Permalink
Raw Message
I managed to get transparency in an FBO like this:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

After that, drawing is made to the FBO; then the whole
thing is drawn to the screen as a 2D texture.

Last, in the GLSL vertex shader, based on position, the
color is changed. However, I don't want this for what is
transparent! I can set alpha but how do I determine if
the current vertex is transparent or not?

Let me know if you need more context.
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Andy V
2013-10-22 02:06:35 UTC
Permalink
Raw Message
Post by Emanuel Berg
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Well, this is really "translucency" rather than "transparency" -- for transparency you can just enable the alpha test. However, what this does is set a new color into the FBO using (a) the old color in the FBO, (b) the new color from the fragment and (c) the alpha value from the fragment. In particular, there is no reference to or need for an alpha value in the FBO.

Does your FBO have stored alpha values or just RGB values?
Post by Emanuel Berg
After that, drawing is made to the FBO; then the whole
thing is drawn to the screen as a 2D texture.
Do you mean you are using the FBO as a 2D texture while drawing some geometry?
Post by Emanuel Berg
Last, in the GLSL vertex shader, based on position, the
color is changed. However, I don't want this for what is
transparent! I can set alpha but how do I determine if
the current vertex is transparent or not?
If your vertex shader is looking up the 2D texture, it can access the looked-up alpha value (assuming the FBO/2D-texture has alpha values).

If you don't have alpha, perhaps you can reserve some known RGB value for "transparent" and check for that in the vertex shader.
Emanuel Berg
2013-10-22 21:33:48 UTC
Permalink
Raw Message
Post by Andy V
Post by Emanuel Berg
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Well, this is really "translucency" rather than
"transparency"
Aha, OK!

Anyway, if you could help me with this I would be so, so
thankful! I've been working on this for ages and my
teacher is unavailable.

The task is to draw a 3D texture with *ray tracing*.

There were some clues how to do this, and I've done all
that:

1. Draw a 3D cube.
2. From that cube, create two textures of
coordinates. The front of the cube, and the back. Those
textures are 2D, and the coordinates are encoded as RGB.

Now, I try to draw the same 3D cube, only instead of
doing the RGB textures, I try to trace the ray and for
each step look in the 3D texture and add that to the
final color.

Only, I don't understand what "ray" - is it from the
point of view, through the cube? Should I somehow use
the front and back positions, to calculate the
corresponding position in the texture?

Is this to be done in the fragment shader? If so, how do
I know if the current pixel is even drawing the cube?

Thanks :)
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Andy V
2013-10-23 00:56:30 UTC
Permalink
Raw Message
Post by Emanuel Berg
The task is to draw a 3D texture with *ray tracing*.
More terminology. Ray *tracing* suggests following following rays of light through a scene, with interactions with surfaces (and possibly volumes) that can cause reflection, refraction, absorption, emission or some of each. It often involves multiple light sources and shadowing, including self-shadowing. It has been done in a GPU, but it is certainly not a simple task.

Ray *casting* is much simpler, and is used in direct volume rendering to follow straight rays (no reflection, no refraction) through a volume handling absorption and emission only. Typically there is one light source, but a small number of is possible. Ray casting is inefficient in that you follow one ray from entry to exit, move on to the next ray and then you need to reload many of the same values from the volume.

In a commercial ray casting engine I worked with, it followed not one ray through the volume but an 8x8 bunch of rays. This gave much better locality of reference.

A much simpler approach (algorithmically equivalent to ray casting) is to render slices through the volume, parallel to the screen. There are lots of optimizations that need to be done to make this fast enough to be practical for large volumes (1Kx1Kx4K, for example). There's a lot of literature out there in Siggraph proceedings and other places.
Post by Emanuel Berg
There were some clues how to do this, and I've done all
1. Draw a 3D cube.
2. From that cube, create two textures of
coordinates. The front of the cube, and the back. Those
textures are 2D, and the coordinates are encoded as RGB.
Now, I try to draw the same 3D cube, only instead of
doing the RGB textures, I try to trace the ray and for
each step look in the 3D texture and add that to the
final color.
Only, I don't understand what "ray" - is it from the
point of view, through the cube? Should I somehow use
the front and back positions, to calculate the
corresponding position in the texture?
Each ray goes through the 3D texture as determined by the eye point and transformation (parallel or perspective as you desire). Each ray also goes through screen space from front to back in a parallel manner.
Post by Emanuel Berg
Is this to be done in the fragment shader? If so, how do
I know if the current pixel is even drawing the cube?
Simplest way: the fragment shader checks to see if its coordinates are inside the 3D texture.

Next simplest: don't draw a rectangle the size of the screen, but only draw the polygon that represents the silhouette of the cube. (Hint: it could be a hexagon.)

Now, if you put a long loop in the fragment shaders, the GPU will bog down doing this ray casting. If this GPU is also driving your display, it will prevent other programs drawing to it. Various operating systems (Windows for one) do not like this and can terminate the program. ("It must be in an infinite loop -- it hasn't completed in 1 second.") Instead, do a little work at a time, decide if you are done, repeat. That is, do "n" steps and save the results in an FBO. When you repeat, start from that FBO, do "n" steps and save the results in a new FBO. If "n" is 1, this is almost my "much simpler approach" above. Hybrid approaches abound -- doing 8x8 patches with larger values for "n", for example.

I hope I've given you enough information to get to the next step.

--
Andy V
Emanuel Berg
2013-10-24 22:09:46 UTC
Permalink
Raw Message
More terminology ...
Thanks a lot, I will print your reply and try to
understand it. I did some experimentation since, with
screenshots if you would like to take a look. There are
actually three "runs" in the code below (see the
comments).

I'm still lost - for example, I don't get why the front
and back positions must be stored. If it is a cube,
aren't those deductible somehow? Or even more, isn't it
always *the same* vector from the front, to the back, no
matter where on the front side you place it?

#version 120

uniform sampler2D tex_back;
uniform sampler2D tex_front;
uniform sampler3D tex_foot;

void main() {
float view_side = 600.0;
vec2 coord = vec2(gl_FragCoord.x, gl_FragCoord.y)/view_side;

vec3 foot_coord;

/* if this is set to red, and the two below attempts
commented out, the result is as in:
Loading Image... */
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);

/* this (the below code) produces some result - see
the dump - but it doesn't look like anything
sensible, besides there is no use of the back and
front positions. */

/* dump: Loading Image... */

for (float z = 0.0; z < 1.0; z += 0.1) {
foot_coord = vec3(coord.x, coord.y, z);
color += texture3D(tex_foot, foot_coord).rgba;
}

/* this (the code below) makes sense in the sense
that iteration is made on the basis of the front
and back positions, namely on the z axis. I just
did it with hopes it would produce some results
that could be interpreted, but it doesn't show
anything, just gray, not even a black box */

/* vec3 front_pos = texture2D(tex_front, coord).rgb; */
/* vec3 back_pos = texture2D(tex_back, coord).rgb; */

/* for (float z = front_pos.b; z < back_pos.b; z += 0.1) { */
/* foot_coord = vec3(front_pos.r, front_pos.g, z); */
/* color += texture3D(tex_foot, foot_coord).rgba; */
/* } */

gl_FragColor = color;
}
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Nobody
2013-10-25 00:47:56 UTC
Permalink
Raw Message
I'm still lost - for example, I don't get why the front and back positions
must be stored. If it is a cube, aren't those deductible somehow?
Yes, but it's more efficient to use the hardware to perform forward
rendering than to perform the inverse calculation for each fragment.
Or even
more, isn't it always *the same* vector from the front, to the back, no
matter where on the front side you place it?
No, because you want the coordinates in object space, so for a given
pixel, the start point, end point, and difference vector will depend upon
the cube's orientation.
#version 120
uniform sampler2D tex_back;
uniform sampler2D tex_front;
uniform sampler3D tex_foot;
void main() {
float view_side = 600.0;
vec2 coord = vec2(gl_FragCoord.x, gl_FragCoord.y)/view_side;
This can be written as:

vec2 coord = gl_FragCoord.xy / view_side;

You don't need to extract individual components then recombine them.

Also, you probably don't need (or want) normalised texture
coordinates. The textures should have the same dimension as the
window, so you can just use the raw window coordinates with
texelFetch() (after converting to an integer), e.g.:

ivec2 coord = ivec2(gl_FragCoord.xy);
vec3 front_pos = texelFetch(tex_front, coord).xyz;
vec3 back_pos = texelFetch(tex_back, coord).xyz;

If you want to use normalised texture coordinates, replacing view_size
with textureSize(tex_back, 0) would be more robust than a hard-coded
constant.
/* this (the code below) makes sense in the sense
that iteration is made on the basis of the front
and back positions, namely on the z axis. I just
did it with hopes it would produce some results
that could be interpreted, but it doesn't show
anything, just gray, not even a black box */
/* vec3 front_pos = texture2D(tex_front, coord).rgb; */
/* vec3 back_pos = texture2D(tex_back, coord).rgb; */
/* for (float z = front_pos.b; z < back_pos.b; z += 0.1) { */
/* foot_coord = vec3(front_pos.r, front_pos.g, z); */
/* color += texture3D(tex_foot, foot_coord).rgba; */
/* } */
Because front_pos and back_pos are (or should be) in object space,
there's no guarantee that front_pos.b < back_pos.b. If they are the
other way around, the loop won't even perform one iteration.

The iteration should look more like:

float step = 10.0 / length(back_pos - front_pos);
for (float t = 0; t < 1; t += step) {
vec3 foot_coord = mix(front_pos, back_pos, t);
color += texture3D(tex_foot, foot_coord).rgba;
}

The step size is calculated so that the number of steps is
proportional to the length of the line segment.
Emanuel Berg
2013-10-25 01:36:43 UTC
Permalink
Raw Message
This can be written as ...
Thanks! I rewrote it as the code below, because
texelFetch doesn't seem to exist (?). But what you say
makes sense! (I hope I didn't break it.)

Anyway, the code below produces no output - just gray!
And it gets worse: if I set the color to red, and a =
1.0, and then run the iteration with nothing to do
(i.e., I don't change the color), the result is the
same: gray nothing.

Is it possible the code overworks the fragment shader,
so it just returns nothing instead of exiting on an
error?

#version 120

uniform sampler2D tex_back;
uniform sampler2D tex_front;
uniform sampler3D tex_foot;

void main() {
vec2 coord = vec2(gl_FragCoord.xy)/600.0;

vec3 front_pos = texture2D(tex_front, coord).xyz;
vec3 back_pos = texture2D(tex_back, coord).xyz;

vec4 color = vec4(0.0, 0.0, 0.0, 0.0);

float step = 10.0/length(back_pos - front_pos);

for (float t = 0.0; t < 1.0; t += step) {
vec3 foot_coord = mix(front_pos, back_pos, t);
color += texture3D(tex_foot, foot_coord).rgba;
}

gl_FragColor = color;
}
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Nobody
2013-10-25 01:52:04 UTC
Permalink
Raw Message
Post by Emanuel Berg
Thanks! I rewrote it as the code below, because
texelFetch doesn't seem to exist (?).
Ah; "#version 120". texelFetch() was added in GLSL 1.3.

If you need to support GLSL 1.2, then you can just use normalised
coordinates instead.
Post by Emanuel Berg
But what you say
makes sense! (I hope I didn't break it.)
Anyway, the code below produces no output - just gray!
And it gets worse: if I set the color to red, and a =
1.0, and then run the iteration with nothing to do
(i.e., I don't change the color), the result is the
same: gray nothing.
Is it possible the code overworks the fragment shader,
so it just returns nothing instead of exiting on an
error?
Have you checked that the contents of the front and back textures are
sane? If there was a problem with that part, the rest of it will be wrong.

Also, there was an error in my previous version:

float step = 10.0/length(back_pos - front_pos);

should have been e.g.:

float step = 0.1/length(back_pos - front_pos);

The result of length() is at most sqrt(3) (front_pos and back_pos lie on
the unit cube), and step needs to be less than 1 (the number of iterations
is floor(1/step)).
Emanuel Berg
2013-10-25 19:25:58 UTC
Permalink
Raw Message
Post by Nobody
Have you checked that the contents of the front and
back textures are sane? If there was a problem with
that part, the rest of it will be wrong.
Thanks so much for your help!

The front and back 2D textures look like this

Loading Image...
Loading Image...

when I run the below fragment shader (the second code
block).

The textures were setup in *another* GLSL program, but
in the vertex shader, like this:

#version 120

void main() {
gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
gl_FrontColor = vec4(gl_Position.x,
gl_Position.y,
gl_Position.z,
1.0);
}

#version 120

uniform sampler2D tex_back;
uniform sampler2D tex_front;
uniform sampler3D tex_foot;

void main() {
vec2 coord = vec2(gl_FragCoord.xy)/600.0;

vec3 front_pos = texture2D(tex_front, coord).xyz;
vec3 back_pos = texture2D(tex_back, coord).xyz;

/* vec4 color = vec4(front_pos.x, front_pos.y, front_pos.z, 1.0); */
vec4 color = vec4(back_pos.x, back_pos.y, back_pos.z, 1.0);

gl_FragColor = color;
}
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Nobody
2013-10-27 03:02:28 UTC
Permalink
Raw Message
Post by Emanuel Berg
Post by Nobody
Have you checked that the contents of the front and
back textures are sane? If there was a problem with
that part, the rest of it will be wrong.
Thanks so much for your help!
The front and back 2D textures look like this
http://user.it.uu.se/~embe8573/front.png
http://user.it.uu.se/~embe8573/back.png
Those are wrong. The colours should follow the shape of the cube, as if
you had assigned one of the 8 primary colours to each vertex while
rendering the cube using the fixed-function pipeline.
Post by Emanuel Berg
when I run the below fragment shader (the second code
block).
The textures were setup in *another* GLSL program, but
#version 120
void main() {
gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
gl_FrontColor = vec4(gl_Position.x,
gl_Position.y,
gl_Position.z,
1.0);
}
gl_FrontColor should be derived from the object-space coordinates
(gl_Vertex), not the clip coordinates (gl_Position).

That's the whole point of rendering the coordinates into a texture: so
that you can easily obtain the object-space coordinates of the points
where the ray intersects the cube.

The clip coordinates can be trivially derived from gl_FragCoord (by
applying the inverse of the viewport transformation), so there wouldn't be
any point in storing those.
Emanuel Berg
2013-10-27 16:00:28 UTC
Permalink
Raw Message
Post by Nobody
Those are wrong. The colours should follow the shape
of the cube, as if you had assigned one of the 8
primary colours to each vertex while rendering the
cube using the fixed-function pipeline.
I changed from gl_Position to gl_Vertex in the vertex
shader, and got two new dumps (URLs last).

However, they don't fit your description all the
same. Is the *front* correct? I got the back by rotating
before capture. Perhaps I rotated around the wrong axis?
Or is that hack non-applicable now that I work in
gl_Vertex and not gl_Position space? (But *something*
happened, as the dumps are not the same.)

This is the code who did that:

void Scene::draw_back() {
glUseProgram(tex_coord_shader);
glPushMatrix();
glRotatef(180, 1.0, 0.0, 0.0);
back_FBO.render_to_me();
draw_cube();
back_FBO.render_to_me_done();
glPopMatrix();
glUseProgram(NONE);
}

Here are the new dumps:

http://user.it.uu.se/~embe8573/front.png
http://user.it.uu.se/~embe8573/back.png
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Nobody
2013-10-27 20:24:41 UTC
Permalink
Raw Message
Post by Nobody
Those are wrong. The colours should follow the shape of the cube, as if
you had assigned one of the 8 primary colours to each vertex while
rendering the cube using the fixed-function pipeline.
I changed from gl_Position to gl_Vertex in the vertex shader, and got two
new dumps (URLs last).
Those look roughly the same as the previous versions (although I can't be
sure because they replace the previous versions).

Maybe caching is interfering? (force-refresh doesn't help). Try giving
them different filenames just to be sure.
However, they don't fit your description all the same. Is the *front*
correct? I got the back by rotating before capture. Perhaps I rotated
around the wrong axis? Or is that hack non-applicable now that I work in
gl_Vertex and not gl_Position space? (But *something* happened, as the
dumps are not the same.)
You should render the cube twice, once with glCullFace(GL_FRONT) and once
with glCullFace(GL_BACK), both times with glEnable(GL_CULL_FACE). The
transformation should be identical in both cases.
Emanuel Berg
2013-10-27 20:33:31 UTC
Permalink
Raw Message
Post by Nobody
Those look roughly the same as the previous versions
(although I can't be sure because they replace the
previous versions).
Maybe caching is interfering? (force-refresh doesn't
help). Try giving them different filenames just to be
sure.
Do you see the window border and part of the terminal
behind them in the dumps? If not, they are the new
ones. The old ones were based on gl_Position.x, .y, and
.z, and one rotation in between to get the back (the C++
code I posted). The result was one reddish slice, and one
bluish.

Those *new* are the result of the exact same, only with
gl_Vertex, not gl_Position. They turned out one red-ish,
and the other one also red-ish, only it seems "rotated"
(?).
Post by Nobody
You should render the cube twice, once with
glCullFace(GL_FRONT) and once with
glCullFace(GL_BACK), both times with
glEnable(GL_CULL_FACE). The transformation should be
identical in both cases.
Aha, cool! Will try that, now :)
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Emanuel Berg
2013-10-27 20:53:27 UTC
Permalink
Raw Message
Post by Nobody
You should render the cube twice, once with
glCullFace(GL_FRONT) and once with
glCullFace(GL_BACK), both times with
glEnable(GL_CULL_FACE). The transformation should be
identical in both cases.
Loading Image...
Loading Image...

One red, and one blue. They look sort of like the ones I
got with gl_Position and the rotation stunt, but those
new are much brighter!

Do they look correct to you?
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Andy V
2013-10-27 22:49:40 UTC
Permalink
Raw Message
Post by Emanuel Berg
Do they look correct to you?
No, the colors should fill the entire projection of the cube -- a pentagon in this case. One point should be white, representing position (1,1,1) and one point black, representing (0,0,0); other vertices are red, green, blue, cyan, magenta and yellow. In these two PNG files, the color hint towards those color but get cut off.

--
Andy V
Emanuel Berg
2013-10-27 23:25:31 UTC
Permalink
Raw Message
Post by Andy V
One point should be white, representing position
(1,1,1) and one point black, representing (0,0,0);
other vertices are red, green, blue, cyan, magenta
and yellow.
In front_with_cull.png, isn't the colors red, yellow,
green, and black?

With black at (0,0,0)?

And in back_with_cull.png: magenta, white, cyan, blue?

With white at (1,1,1)?
Post by Andy V
In these two PNG files, the color hint towards those
color but get cut off.
Are you saying: red (for example), is not maximum red,
either the red component is not 100% emphasized, *or* it
still has some green and/or blue in it?
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Nobody
2013-10-27 23:02:24 UTC
Permalink
Raw Message
Post by Emanuel Berg
Do they look correct to you?
No. The colours should fit the cube, not a square.
Emanuel Berg
2013-10-27 23:30:22 UTC
Permalink
Raw Message
Post by Nobody
Post by Emanuel Berg
Do they look correct to you?
No. The colours should fit the cube, not a square.
I'm not following... how do you mean "fit"?

Those textures are of the front and back sides of the
cube so they are square. The textures are 2D, but were
apprehended by drawing the 3D cube on their respective
FBOs.

But perhaps you meant something else?
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Nobody
2013-10-28 01:16:28 UTC
Permalink
Raw Message
Post by Emanuel Berg
Post by Nobody
No. The colours should fit the cube, not a square.
I'm not following... how do you mean "fit"?
If you look at back_with_cull.png, there shouldn't be any black pixels.
Any pixel covered by the shape of the projected cube should be coloured.

You should see a coloured cube, not a black cube with a coloured square
drawn over the top of it.
Emanuel Berg
2013-10-29 22:49:32 UTC
Permalink
Raw Message
Post by Nobody
If you look at back_with_cull.png, there shouldn't be
any black pixels. Any pixel covered by the shape of
the projected cube should be coloured.
You should see a coloured cube, not a black cube with
a coloured square drawn over the top of it.
Aha, I see! Thanks for your patience!

Is is correct now? With colors based on the vertex xyz
(in the vertex shader), and then back and front with the
cull method you showed me (in the C++ source).

Loading Image...
Loading Image...
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Andy V
2013-10-30 01:50:01 UTC
Permalink
Raw Message
Post by Emanuel Berg
Is is correct now? With colors based on the vertex xyz
(in the vertex shader), and then back and front with the
cull method you showed me (in the C++ source).
http://user.it.uu.se/~embe8573/front_whole_cube.png
http://user.it.uu.se/~embe8573/back_whole_cube.png
Yes, these are correct now, at least from a quick glance. Black (0,0,0) is opposite white (1,1,1); red (1,0,0), green (0,1,0) and blue (0,0,1) are next to black; and yellow (1,1,0), cyan (0,1,1) and magenta (1,0,1) are next to white.

Now for the second stage!

--
Andy V
Emanuel Berg
2013-10-30 01:57:10 UTC
Permalink
Raw Message
Post by Andy V
Post by Emanuel Berg
Is is correct now? With colors based on the vertex
xyz (in the vertex shader), and then back and front
with the cull method you showed me (in the C++
source).
http://user.it.uu.se/~embe8573/front_whole_cube.png
http://user.it.uu.se/~embe8573/back_whole_cube.png
Yes, these are correct now, at least from a quick
glance. Black (0,0,0) is opposite white (1,1,1); red
(1,0,0), green (0,1,0) and blue (0,0,1) are next to
black; and yellow (1,1,0), cyan (0,1,1) and magenta
(1,0,1) are next to white.
Amazing!
Post by Andy V
Now for the second stage!
What's that?!
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Andy V
2013-10-30 02:12:27 UTC
Permalink
Raw Message
Post by Emanuel Berg
Post by Andy V
Now for the second stage!
What's that?!
The main ray casting engine.

--
Andy V
Emanuel Berg
2013-10-30 22:49:26 UTC
Permalink
Raw Message
Now for the second stage ... The main ray casting
engine.
That hasn't change. What has changed is:

* gl_Vertex instead of gl_Position in the vertex shader
of the first GLSL program (the one who mapped position
to color)

But: that mapping is still stored in two *2D*
textures, and I believe that is to be so, as those
were setup (as 2D textures, associated with FBOs named
front and back) in the skeleton code provided.

* instead of applying a transformation (rotation) to get
the back of the cube, the cull front and back method

The below fragment shader (the ray tracer, in the
*second* GLSL program), doesn't produce any output when
I draw the cube (an uncolored version, for the fragment
shader to fill from the 3D texture) - I just get a gray
window.

I don't know if there is anything in the fragment
shader, or in the "normal" source code. Should I draw a
3D box? If not, what should I draw? Because I have to
draw *something*, otherwise the fragment shader won't
have anything to shade, right?

Well, gentlemen, have a look below. I run some
experimentation meanwhile...

#version 120

uniform sampler2D tex_back;
uniform sampler2D tex_front;
uniform sampler3D tex_foot;

void main() {
vec2 coord = vec2(gl_FragCoord.xy)/600.0;

vec3 front_pos = texture2D(tex_front, coord).xyz;
vec3 back_pos = texture2D(tex_back, coord).xyz;

vec4 color = vec4(0.0, 0.0, 0.0, 0.0);

float step = 0.1/length(back_pos - front_pos);

for (float t = 0.0; t < 1.0; t += step) {
vec3 foot_coord = mix(front_pos, back_pos, t);
color += texture3D(tex_foot, foot_coord).rgba;
}

gl_FragColor = color;
}
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Andy V
2013-10-31 00:59:05 UTC
Permalink
Raw Message
Post by Emanuel Berg
The below fragment shader (the ray tracer, in the
*second* GLSL program), doesn't produce any output when
I draw the cube (an uncolored version, for the fragment
shader to fill from the 3D texture) - I just get a gray
window.
I don't know if there is anything in the fragment
shader, or in the "normal" source code. Should I draw a
3D box? If not, what should I draw? Because I have to
draw *something*, otherwise the fragment shader won't
have anything to shade, right?
You should draw all the pixels in the projection of the cube.
You may draw all the pixels in the window as long as you initialize
the color correctly.
Post by Emanuel Berg
Well, gentlemen, have a look below. I run some
experimentation meanwhile...
#version 120
uniform sampler2D tex_back;
uniform sampler2D tex_front;
uniform sampler3D tex_foot;
void main() {
vec2 coord = vec2(gl_FragCoord.xy)/600.0;
vec3 front_pos = texture2D(tex_front, coord).xyz;
vec3 back_pos = texture2D(tex_back, coord).xyz;
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
If you change this initial value, say to .1,.1.,0.9,0.0, do you still get
gray values or does it change to this value?
Post by Emanuel Berg
float step = 0.1/length(back_pos - front_pos);
for (float t = 0.0; t < 1.0; t += step) {
vec3 foot_coord = mix(front_pos, back_pos, t);
color += texture3D(tex_foot, foot_coord).rgba;
Why are you simply adding the colors? Generally, you want to blend the colors based on alpha. Given that you are casting front to back, you want to do a saturation blend:
vec4 newcolor = texture3D(tex_foot, foot_coord).rgba;
color.rgb += newcolor.rgb * newcolor.a * ( 1 - color.a );
color.a += newcolor.a * (1 - color.a);

This assumes that the colors in tex_foot are not pre-multiplied by their alpha values. That is, a 50% translucent red is (1,0,0,.5).
Post by Emanuel Berg
}
gl_FragColor = color;
}
--
Andy V
Emanuel Berg
2013-11-01 01:43:30 UTC
Permalink
Raw Message
Post by Andy V
Post by Emanuel Berg
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
If you change this initial value, say to
.1,.1.,0.9,0.0, do you still get gray values or does
it change to this value?
No, this has been why I all along suspected something
*breaks* in the fragment shader - it doesn't matter what
the initial color value is, any "advanced" attempt to do
anything results in a gray screen.

The only "result" I get is the one when I use the
front_pos fox xy, and z = 0.5, then it looks like this:

Loading Image...

For z = 0.1, 0.2, etc. there are similar stuff but even
less to see.

(That screenshot is dark. On my screen, it is somewhat
more "bone" but not much.)
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Nobody
2013-11-03 03:15:02 UTC
Permalink
Raw Message
any "advanced" attempt to do anything results in a gray screen.
Are you checking that the program is compiling and linking successfully?
Emanuel Berg
2013-11-03 12:06:20 UTC
Permalink
Raw Message
Post by Nobody
any "advanced" attempt to do anything results in a
gray screen.
Are you checking that the program is compiling and
linking successfully?
"The program" as in the GLSL fragment shader? Or the C++
program?

I don't get any error messages from either (and I know
even GLSL programs give those), but I haven't done any
more elaborate testing.

The C++ Makefile looks like this:

CC=g++
CFLAGS=-c -Wall -std=c++11 -DGL_GLEXT_PROTOTYPES
GL_LIBS=-lGLEW -lGL -lGLU -lglut
LDFLAGS=$(GL_LIBS) -lm
INCL_PATH=include/
INCL=-I $(INCL_PATH)
EXE=run

SRC=$(wildcard *.cpp callbacks/*.cpp)
OBJ=$(SRC:.cpp=.o)

all: $(SRC) $(EXE)

$(EXE): $(OBJ)
$(CC) $(LDFLAGS) $(OBJ) -o $@

%.o: %.cpp include/%.hh
$(CC) $(CFLAGS) $(INCL) -o $@ $<
%.o: %.cpp
$(CC) $(CFLAGS) $(INCL) -o $@ $<

clean:
rm -rf run $(OBJ)
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Cathy L.
2013-11-03 16:51:42 UTC
Permalink
Raw Message
Post by Emanuel Berg
I don't get any error messages from either (and I know
even GLSL programs give those), but I haven't done any
more elaborate testing.
Hello
I guess Nobody talks about checking the GLSL program at
compiling/linking time, like explained here:
http://www.opengl.org/wiki/OpenGL_Shading_Language#Error_Checking
Hope this helps
Cathy L.
Emanuel Berg
2013-11-06 01:31:53 UTC
Permalink
Raw Message
Post by Cathy L.
I guess Nobody talks about checking the GLSL program
at compiling/linking time ...
Thanks. I implemented the test function [1]. Have a
look.

It gives the "Everything is OK with the shaders.", so I
guess that's a good sign.

[1] http://user.it.uu.se/~embe8573/test.cpp
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Nobody
2013-11-07 14:56:14 UTC
Permalink
Raw Message
Post by Emanuel Berg
Thanks. I implemented the test function [1]. Have a
look.
Personally, I would print the info log regardless of the compile/link
status, in case it compiles but with warnings.
Emanuel Berg
2013-11-08 23:54:20 UTC
Permalink
Raw Message
Post by Nobody
Post by Emanuel Berg
Thanks. I implemented the test function [1]. Have a
look.
Personally, I would print the info log regardless of
the compile/link status, in case it compiles but with
warnings.
Good thinking, I did just that (I hope) [1] but either I
set it up the wrong way (I used this page [2] as a
guide) *or* there just isn't any warnings. I get "no
messages" on all three (the vertex shader, the fragment
shader, and linking).

[1] http://user.it.uu.se/~embe8573/test.cpp
[2] http://svn.clifford.at/tools/trunk/examples/gldemo.c
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Emanuel Berg
2013-11-12 01:25:31 UTC
Permalink
Raw Message
I have learned that I should not accumulate everything
along the ray, instead I should apply so called MIP
("Maximum Intensity Projection") and pick the
*brightest* color along the ray.

I was unsure as what "brightness" was in this case. So I
just added the RGB components and the color with the
highest sum was deemed the most bright.

I still get the same (lack of) result, and no errors or
warnings. You can check out the new fragment shader at

http://user.it.uu.se/~embe8573/ass4/glsl/tracerFragment.glsl
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Andy V
2013-11-14 00:41:41 UTC
Permalink
Raw Message
Post by Emanuel Berg
I have learned that I should not accumulate everything
along the ray, instead I should apply so called MIP
("Maximum Intensity Projection") and pick the
*brightest* color along the ray.
You certainly *may* use MIP, but I don't think it is very useful
for a number of reasons -- one being that it depends on the exact
samples taken more that other functions.

The accumulation functions discussed earlier are more common in
direct volume rendering.
Post by Emanuel Berg
I was unsure as what "brightness" was in this case. So I
just added the RGB components and the color with the
highest sum was deemed the most bright.
There are a few different calculations of brightness; usually weighted towards green since that's the way the human eye perceives brightness.
Post by Emanuel Berg
I still get the same (lack of) result, and no errors or
warnings. You can check out the new fragment shader at
http://user.it.uu.se/~embe8573/ass4/glsl/tracerFragment.glsl
You could try other shaders (say, counting the number of fragments),
but given the consistent lack of results, my guess is that the
problem is elsewhere. Z buffering, blend mode, or something else
I don't know.
--
Andy V
Emanuel Berg
2013-11-14 01:06:06 UTC
Permalink
Raw Message
Post by Andy V
You certainly *may* use MIP, but I don't think it is
very useful for a number of reasons -- one being that
it depends on the exact samples taken more that other
functions.
The accumulation functions discussed earlier are more
common in direct volume rendering.
I got that piece of information from the teacher's
assistant. There is no mention of MIP in the
instruction so I wonder how they thought one should
figure that out.
Post by Andy V
There are a few different calculations of brightness;
usually weighted towards green since that's the way
the human eye perceives brightness.
The assistant also said the foot texture has the *same*
value in all three channels (R, G, and B) - so there is
no point summing, instead I should just pick one (say
R) and compare that to the highest so far (I guess) to
get the highest value.
Post by Andy V
You could try other shaders (say, counting the number
of fragments)
Yes, I thought of that, but do you remember those RGB
cubes that I posted? That was done in a GLSL shader as
well (the *vertex* shader). Also, in the ray tracer
(fragment) shader, when I commented out the loop (which
iterated the volume along the rays) and just set the
fragments to red, indeed I got a red cube. So I think
there is something wrong with how the texture gets
accessed.
Post by Andy V
but given the consistent lack of results
You nailed it, that's a good way to describe it :)
Post by Andy V
my guess is that the problem is elsewhere. Z
buffering, blend mode
I have a book on OpenGL now, so let me look those
things up. Feel free to elaborate nonetheless, of
course.
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Emanuel Berg
2013-11-15 00:48:13 UTC
Permalink
Raw Message
Post by Andy V
You could try other shaders (say, counting the number
of fragments), but given the consistent lack of
results, my guess is that the problem is elsewhere. Z
buffering, blend mode, or something else I don't
know.
I downloaded and run glslDevil [1], a debugger for
shaders. I also had to install qt4-default - for the
GUI, I take it.

Often when I do stuff in the debugger, it exits on a
segmentation fault, so it doesn't seem stable at
all. Nonetheless, I managed to run the program (the C++
binary) and get some output.

It seems, *before* the fragment ray tracer shader is
loaded, there is a warning, that then is recurring
Post by Andy V
W! OpenGL error GL_INVALID_OPERATION detected
The whole trace file:

http://user.it.uu.se/~embe8573/trace.txt

[1] http://wwwvis.informatik.uni-stuttgart.de/glsldevil/index.html
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Andy V
2013-11-15 02:53:23 UTC
Permalink
Raw Message
contains:

glEnable(GL_TEXTURE_3D)
| glActiveTexture(GL_TEXTURE2)
| glBindTexture(GL_TEXTURE_3D, 1)
| glGetUniformLocation(6, 0x804ebf3)
| glUniform1i(65536, 2)
| glDisable(GL_TEXTURE_3D)

It appears that you don't keep the 3D texture enabled long enough to be useful.

--
Andy V
Emanuel Berg
2013-11-16 17:42:29 UTC
Permalink
Raw Message
Post by Andy V
glEnable(GL_TEXTURE_3D)
glActiveTexture(GL_TEXTURE2)
glBindTexture(GL_TEXTURE_3D, 1)
glGetUniformLocation(6, 0x804ebf3)
glUniform1i(65536, 2)
glDisable(GL_TEXTURE_3D)
It appears that you don't keep the 3D texture enabled
long enough to be useful.
Are you saying I shouldn't do that? In scene.cpp, it
looks like this:

void Scene::setup_foot_tex() {
glEnable(GL_TEXTURE_3D);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_3D, volume.tex);
glUniform1i(glGetUniformLocation(tracer_shader, "tex_foot"), 2);
glDisable(GL_TEXTURE_3D);
}

Also, I have made yet another attempt to debug this. By
now, I believe that the problem is *not* the fragment
shader, but the C++ source. Below, I have yanked the
functions that are unclear. The comments refer to the
line immediately after. The rest of the functions are
not an issue - I just provide them for context. I think
it would probably be best to view the original files in
your preferred editor, with highlight and so on, but I
provide them here as well if you for some reason don't
want to do that.

Entire project: http://user.it.uu.se/~embe8573/ass4/

Problems in scene.cpp:
(whole file: http://user.it.uu.se/~embe8573/ass4/scene.cpp )

void Scene::resize_update_shaders() {
GLint win_size[2] = {viewport_size.x, viewport_size.y};
// below code line will give:
// OpenGL error: 1282 ('invalid operation')
glUniform1iv(glGetUniformLocation(tracer_shader, "window"), 2,
win_size);
}

void Scene::setup_foot_tex() {
glEnable(GL_TEXTURE_3D);

// makes cube *black* on draw_cube() - ? -
// if this function isn't called, the cube is *white*
glActiveTexture(GL_TEXTURE2);

glBindTexture(GL_TEXTURE_3D, volume.tex);

// 1282
glUniform1i(glGetUniformLocation(tracer_shader, "tex_foot"), 2);

glDisable(GL_TEXTURE_3D);
}

void Scene::setup_front_tex() {
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, front_FBO.get_tex());

// 1282
glUniform1i(glGetUniformLocation(tracer_shader, "tex_front"), 0);

glDisable(GL_TEXTURE_2D);
}

void Scene::setup_back_tex() {
glEnable(GL_TEXTURE_2D);

// no draw on 1 or 2 - only 0 works:
// on 1 or 2 there is no draw at all (no cube) on draw_cube()
// can I have 0 here if I have it in setup_front_tex()
// as well?
glActiveTexture(GL_TEXTURE0);

glBindTexture(GL_TEXTURE_2D, back_FBO.get_tex());

// 1282
glUniform1i(glGetUniformLocation(tracer_shader, "tex_back"), 0);

glDisable(GL_TEXTURE_2D);
}

Problems in frame_buffer_object.cpp:
(whole file: http://user.it.uu.se/~embe8573/ass4/frame_buffer_object.cpp )

void Frame_Buffer_Object::create(Vec2i dim_) {
if (dim_.x <= 0 || dim_.y <= 0) {
std::cerr << "Cannot create FBO: zero size!\n";
}
else {
dim = dim_;

gen_tex();
bind_tex();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, NO_MIPMAP, GL_RGBA,
dim.x, dim.y, NO_TEX_BORDER,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);

gen_fb();
bind_fb();

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, tex, 0);
glGenBuffers(NUM_FBS, &depth);

// 1282 block start
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
GL_DEPTH_COMPONENT24,
dim.x, dim.y);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT,
depth);
// 1282 block end

GLenum fbo_err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (fbo_err != GL_FRAMEBUFFER_COMPLETE_EXT) {
fbo_error(fbo_err);
}
clear();
unbind_fb();
created = true;
}
}
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Andy V
2013-11-17 15:48:33 UTC
Permalink
Raw Message
Post by Emanuel Berg
Post by Andy V
It appears that you don't keep the 3D texture enabled
long enough to be useful.
Are you saying I shouldn't do that? In scene.cpp, it
Well, I am much more comfortable with the old fixed function OpenGL paragigms, where disabling 3D texture meant just that. I don't know if you need to keep the 3D texture enabled or not when using a shader program.

Can anybody answer this definitively? Can Nobody?
Post by Emanuel Berg
void Scene::resize_update_shaders() {
GLint win_size[2] = {viewport_size.x, viewport_size.y};
// OpenGL error: 1282 ('invalid operation')
glUniform1iv(glGetUniformLocation(tracer_shader, "window"), 2,
win_size);
Is it the glGetUniformLocation or the glUniform1iv returning the error? Does glGetUniformLocation return -1? Has tracer_shader been initialized by now?
Post by Emanuel Berg
void Scene::setup_foot_tex() {
glEnable(GL_TEXTURE_3D);
// makes cube *black* on draw_cube() - ? -
// if this function isn't called, the cube is *white*
The 2 in GL_TEXTURE2 must match the 2 in the glUniform1i below. However, if you get an error on this, the sampler3D will not reference the right texture.
Post by Emanuel Berg
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_3D, volume.tex);
// 1282
glUniform1i(glGetUniformLocation(tracer_shader, "tex_foot"), 2);
glDisable(GL_TEXTURE_3D);
}
void Scene::setup_front_tex() {
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, front_FBO.get_tex());
// 1282
glUniform1i(glGetUniformLocation(tracer_shader, "tex_front"), 0);
glDisable(GL_TEXTURE_2D);
}
void Scene::setup_back_tex() {
glEnable(GL_TEXTURE_2D);
// on 1 or 2 there is no draw at all (no cube) on draw_cube()
// can I have 0 here if I have it in setup_front_tex()
// as well?
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, back_FBO.get_tex());
// 1282
glUniform1i(glGetUniformLocation(tracer_shader, "tex_back"), 0);
I believe you need GL_TEXTURE1 here, and the second argument to glUniform1i needs to be 1 as well. Otherwise you end up with the same texture used for front and back, which isn't good.

--
Andy V
Emanuel Berg
2013-11-17 17:08:04 UTC
Permalink
Raw Message
Post by Andy V
Is it the glGetUniformLocation or the glUniform1iv
returning the error? Does glGetUniformLocation return
-1? Has tracer_shader been initialized by now?
...
The 2 in GL_TEXTURE2 must match the 2 in the
glUniform1i below. However, if you get an error on
this, the sampler3D will not reference the right
texture.
...
I believe you need GL_TEXTURE1 here, and the second
argument to glUniform1i needs to be 1 as
well. Otherwise you end up with the same texture used
for front and back, which isn't good.
The shaders have been initialized in the sense
*loaded*, as in:

// ...
GLuint vshader = load_shader(vertex_file, GL_VERTEX_SHADER);
GLuint fshader = load_shader(fragment_file, GL_FRAGMENT_SHADER);

GLuint program = glCreateProgram();
if (!program) {
throw std::runtime_error("Can't create program.");
}

glAttachShader(program, vshader);
glAttachShader(program, fshader);

glDeleteShader(vshader);
glDeleteShader(fshader);

glLinkProgram(program);
// ... (from shader.cpp)

Isolating the error by extracting the location reveals
that doing so does *not* produce the error, and the
result isn't -1 either. The error comes from
glUniform1iv (and later on, correspondingly from the
occurrences of glUniform1i). As in:

void Scene::resize_update_shaders() {
GLint win_size[2] = {viewport_size.x, viewport_size.y};

int location = glGetUniformLocation(tracer_shader, "window");
// below code line will give:
// OpenGL error: 1282 ('invalid operation')
if (location != -1) {
glUniform1iv(location, 2, win_size); // here
}
else {
std::cerr << "Couldn't get location: tracer shader, \"window\".\n";
}
}

My intuition also tells me there should be different
textures. The only reason I changed it was because it
didn't work. I changed that back.

Summary:

After drawing the front texture (on GL_TEXTURE0), and
then drawing the cube, the cube is *white*.

After drawing the foot texture (which is 3D, on
GL_TEXTURE2), the cube gets *black*.

After drawing the back texture (2D, on GL_TEXTURE1),
there is no cube. So here, it *breaks*.

Note that I don't see how the texture work should
influence drawing at all. Maybe when mucking around
with that, the default color is somehow changed? I'll
soon test set the color explicitly before draw_cube
(which does not apply the textures or the shaders), and
see what happens.

Another hypothesis: are the textures initialized
correctly?
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Emanuel Berg
2013-11-17 17:18:04 UTC
Permalink
Raw Message
Post by Emanuel Berg
After drawing the front texture (on GL_TEXTURE0), and
then drawing the cube, the cube is *white*.
After drawing the foot texture (which is 3D, on
GL_TEXTURE2), the cube gets *black*.
After drawing the back texture (2D, on GL_TEXTURE1),
there is no cube. So here, it *breaks*.
Note that I don't see how the texture work should
influence drawing at all. Maybe when mucking around
with that, the default color is somehow changed? I'll
soon test set the color explicitly before draw_cube
(which does not apply the textures or the shaders), and
see what happens.
OK, I set the color to red in draw_cube (with
glColor4f(1.0, 0.0, 0.0, 1.0); ) and as expected, the
front foot texture is the only one who doesn't break it
- it gets *red*, but the other two doesn't change
(i.e., the black cube is just as nonfunctional as the
"no cube").
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Emanuel Berg
2013-11-17 23:33:20 UTC
Permalink
Raw Message
Post by Andy V
Well, I am much more comfortable with the old fixed
function OpenGL paragigms, where disabling 3D texture
meant just that. I don't know if you need to keep the
3D texture enabled or not when using a shader
program.
Can anybody answer this definitively? Can Nobody?
I removed all the disable stuff. I found a tutorial on
the web, and they didn't use it.

Now it should be more or less clear why it doesn't
work. The shader doesn't get the textures. Even more,
just trying to set them up will break normal behaviour
(the color red turns into wine red or black, or drawing
breaks altogether).

It works only for:

glActiveTexture(GL_TEXTURE0);
...
glUniform1i(location, 0);

And when I say "works", I mean it doesn't break
anything. I haven't actually tested (at the moment I
don't know how) if the texture is also sent to the
shader.

1 and 2 (instead of 0) doesn't work. The below code
breaks.

void Scene::setup_front_tex() {
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, front_FBO.get_tex());

int location = glGetUniformLocation(tracer_shader, "tex_front");
if (location != -1) {
glUniform1i(location, 1); // 1282
}
else {
std::cerr << "Couldn't get location: tracer shader, \"tex_front\".\n";
}
}

There is so much code to setup the FBOs and their
textures. If you know where to look, check it out here:

http://user.it.uu.se/~embe8573/ass4/frame_buffer_object.cpp
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Emanuel Berg
2013-11-19 02:18:23 UTC
Permalink
Raw Message
Post by Emanuel Berg
Now it should be more or less clear why it doesn't
work. The shader doesn't get the textures. Even more,
just trying to set them up will break normal behaviour
(the color red turns into wine red or black, or drawing
breaks altogether).
I managed to get away with *all* of the "1282" errors!

This line - glGenRenderbuffersEXT(NUM_FBS, &depth); -
was missing!

I've also been able to confirm that the front and back
textures now reaches the ray tracer fragment
shader. Those dumps are drawn from a fragment shader,
which accesses those textures:

Loading Image...
Loading Image...

whole code: http://user.it.uu.se/~embe8573/ass4/

It still doesn't work, but I have yet to confirm that
the 3D foot texture reaches the shader as well.
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Emanuel Berg
2013-11-19 23:05:21 UTC
Permalink
Raw Message
Post by Emanuel Berg
It still doesn't work, but I have yet to confirm that
the 3D foot texture reaches the shader as well.
OK, I can confirm that the foot texture reaches the
shader [1].

Also, iteration now works in the shader! Like this:

float step = 0.1;

Apparently, this line -

/* float step = 0.1/length(back_pos - front_pos); */

- broke the for loop. I don't know why.

The result I get looks grotesque - but could it be a
part of a foot? Check out the dump [2].

Obviously, there is something wrong with the cube. It
shouldn't look like a cube with painted walls, but a
volume (perhaps like a monkey's foot in a museum).

[1] http://user.it.uu.se/~embe8573/ass4/glsl/tracerFragment.glsl
[2] Loading Image...
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Andy V
2013-11-20 03:27:54 UTC
Permalink
Raw Message
Post by Emanuel Berg
Apparently, this line -
/* float step = 0.1/length(back_pos - front_pos); */
- broke the for loop. I don't know why.
Perhaps back_pos equals front_pos giving a NaN in step?
Post by Emanuel Berg
The result I get looks grotesque - but could it be a
part of a foot? Check out the dump [2].
Too many bones for a single foot. However, it may be an issue with the step size.

Why are you getting a square inside the cube? What geometry are using for the volume rendering?

--
Andy V
Emanuel Berg
2013-11-20 03:35:50 UTC
Permalink
Raw Message
Post by Andy V
Perhaps back_pos equals front_pos giving a NaN in
step?
But when I draw the textures from the shader, they
don't look the same. Oh, I should probably get .rgb
instead of .xyz - the same result, though.
Post by Andy V
Why are you getting a square inside the cube? What
geometry are using for the volume rendering?
That's not a square, that's the far inside of the cube
(I think)! Yes, I don't get a volume, I get a cube
"painted" with the texture!

void Scene::draw_cube() {
glPushMatrix();
glTranslatef(-0.5, -0.5, -0.5);
glColor4f(1.0, 0.0, 0.0, 1.0);

glBegin(GL_QUAD_STRIP);
glVertex3f(0,0,1);
glVertex3f(0,0,0);
glVertex3f(1,0,1);
glVertex3f(1,0,0);
glVertex3f(1,1,1);
glVertex3f(1,1,0);
glVertex3f(0,1,1);
glVertex3f(0,1,0);
glVertex3f(0,0,1);
glVertex3f(0,0,0);
glEnd();
glBegin(GL_QUADS);
glVertex3f(0,0,1);
glVertex3f(1,0,1);
glVertex3f(1,1,1);
glVertex3f(0,1,1);

glVertex3f(1,0,0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glVertex3f(1,1,0);
glEnd();
glPopMatrix();
}
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
Emanuel Berg
2013-11-20 17:46:15 UTC
Permalink
Raw Message
I finally met my teacher and he almost instantly
spotted the error. The RGB (position) textures are
setup in the constructor method of the scene, but
before the cube is drawn, the perspective is somewhere
(?) changed, so the textures do not reflect the current
state when employed in the shader.

The foot:
Loading Image...

I deleted the code so future students won't get off
that easy. If you want it, mail me and I will somehow
transfer it to you.

Thank you so much for all your help.
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
me
2013-12-08 15:18:11 UTC
Permalink
Raw Message
;-))

everybody should applicate this type of guidelines
Most artists make the
greatest number of changes at the start of a drawing.
This is a strong
compositional starting point for a three quarter view portrait.
3. Using
larger areas of tone to unite all the elements of the portrait.
Most
artists make the greatest number of changes at the start of a drawing.

There are three basic stages in the creation of the image:
This is a strong
compositional starting point for a three quarter view portrait.
The
hairline on the right side of the face creates a sweeping curve as it meets
the neckline of the t-shirt.
;
We may also notice that, this site gives some ideas http://www.incs.fr;
Now I think that we could try to develop the management of the cube with great
care;
could you show me how to evaluate the texture outsourcing and the cube supervision?

;-)

Nobody
2013-10-31 01:42:20 UTC
Permalink
Raw Message
Post by Emanuel Berg
I don't know if there is anything in the fragment
shader, or in the "normal" source code. Should I draw a
3D box? If not, what should I draw? Because I have to
draw *something*, otherwise the fragment shader won't
have anything to shade, right?
You should draw a quad (or two triangles) which covers the window. You can
"discard" any fragments for which front_pos == back_pos.

If you draw a 3D cube, you should enable culling so that each fragment
only gets drawn once.
Post by Emanuel Berg
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
float step = 0.1/length(back_pos - front_pos);
for (float t = 0.0; t < 1.0; t += step) {
vec3 foot_coord = mix(front_pos, back_pos, t);
color += texture3D(tex_foot, foot_coord).rgba;
}
gl_FragColor = color;
The addition should probably be a blend operation. E.g.:

for (float t = 0.0; t < 1.0; t += step) {
vec3 foot_coord = mix(back_pos, front_pos, t);
vec4 col = texture3D(tex_foot, foot_coord).rgba;
// if tex_foot doesn't use pre-multiplied alpha:
// col.rgb *= col.a;
color = color.rgba * (1 - col.a) + col.rgba;
}

The resulting gl_FragColor has pre-multiplied alpha, so in the client the
blending mode should be:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Andy V
2013-11-01 00:54:14 UTC
Permalink
Raw Message
Post by Emanuel Berg
for (float t = 0.0; t < 1.0; t += step) {
vec3 foot_coord = mix(back_pos, front_pos, t);
vec4 col = texture3D(tex_foot, foot_coord).rgba;
// col.rgb *= col.a;
color = color.rgba * (1 - col.a) + col.rgba;
}
I note that you swapped front and back in the mix function, implying that you are accumulating from back to front. I prefer to accumulate from front to back to be able to stop when alpha gets close to 1.0.
Post by Emanuel Berg
The resulting gl_FragColor has pre-multiplied alpha, so in the client the
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
This is true for both front-to-back and back-to-front accumulation. That is, if you want to blend with a background already in the frame buffer. Since Emanuel Berg appeared to load the frame buffer with neutral gray, I wouldn't bother blending.

--
Andy V
Nobody
2013-10-30 04:27:45 UTC
Permalink
Raw Message
Post by Emanuel Berg
Is is correct now?
Yes.
Nobody
2013-10-25 00:22:12 UTC
Permalink
Raw Message
Anyway, if you could help me with this I would be so, so thankful! I've
been working on this for ages and my teacher is unavailable.
The task is to draw a 3D texture with *ray tracing*.
1. Draw a 3D cube.
2. From that cube, create two textures of coordinates. The front of the
cube, and the back. Those textures are 2D, and the coordinates are encoded
as RGB.
At this point, you should have two window-sized textures. This allows you
to quickly get the 3D object-space coordinates where a given ray
(specified by its window coordinates) enters and exits the cube (assuming
that it actually intersects the cube).
Now, I try to draw the same 3D cube, only instead of doing the RGB
textures, I try to trace the ray and for each step look in the 3D texture
and add that to the final color.
Only, I don't understand what "ray" - is it from the point of view,
through the cube? Should I somehow use the front and back positions, to
calculate the corresponding position in the texture?
Use gl_FragCoord to perform lookups into the textures created in the
first steps above. This gives you the start and end points (in cube
space) of the 3D line segment formed by the intersection of the ray with
the cube.

Then you just need to trace that line through the 3D texture using e.g. a
3D version of Bresenham's algorithm.
Is this to be done in the fragment shader? If so, how do I know if the
current pixel is even drawing the cube?
If the ray doesn't intersect the cube, the corresponding texels from the
textures rendered in the first step will both contain the background
colour.

Assuming that you cleared the textures to the same colour, any ray
for which the two texels have identical values can be assumed not to
intersect the cube. Using a 50% grey background has the advantage that
this cannot occur at any point in the rendered portion; any point on
one of the cube's faces will always have one of the three R/G/B components
equal to either 0 or 1.
Loading...