We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
P3D fill and texture (Read 1464 times)
P3D fill and texture
Oct 12th, 2005, 4:19pm
 
I'm currently working on a terrain engine, and in an effort to reduce the number of visible polygons at any one point, I manually tint each one with a percentage of a "mist" colour up to 100% depending on distance form the camera, and over a certain distance stop drawing them altogether.

Now, this works fine, if applied to untextured polygons, but using it with textured ones causes problems, since the texture  seems to be subtractive from the fill color, meaning that any non-white texture never fully fades into the mist, since the dark spots are still darker than the desired colour.

The effect can be seen in these 2 screenshots:
No texture:
...
With texture: (The all white polygons are caused by a bug I'm just going to go report...)
...

The code for the colouring is identicel for both views, one just uses vertex(x,y,z) with no texture, the other uses vertex(x,y,z,u,v) and a texture, the fill() calls are the same calls in both cases.

So as you can see in the textured one, the "far" polygons stil have significant dark spots, and as such don't blend into the sky/mist colour.

Is there any way to change the texture/fill blending method? or a not too computationally expensive way to blend a texture into a colour?

Or should I start looking for yet another way to do a depth-fog style effect?
Re: P3D fill and texture
Reply #1 - Oct 12th, 2005, 8:21pm
 
john, openGL has built-in support for fogging and is well explained in this NeHe tutorial. Even though the main tutorial is for C/C++ there's a list of links to ports to other languages (incl. Java) at end of the article. I assume in Processing you'll somehow have to get hold of the GL instance directly to apply those settings, but am not sure how to do it off the top of my hat... but am guessing like this:

Code:
import processing.opengl.*

GL gl;

void setup() {
size(400,400);
gl=g.gl;
}

void draw() {
gl.glFogi(GL_FOG_MODE, GL_LINEAR);
gl.glFogf(GL_FOG_START,0f);
gl.glFogf(GL_FOG_END, 5.0f);
...
}
Re: P3D fill and texture
Reply #2 - Oct 13th, 2005, 1:09pm
 
Unfortunately OpenGL isn't really an option, as I'm wanting this to be an applet online eventually.
Re: P3D fill and texture
Reply #3 - Oct 13th, 2005, 6:50pm
 
You could modify the processing P3D engine to support fog. Wink  It'd probably be more effective/efficient than any kind of workaround.

Marcello
Re: P3D fill and texture
Reply #4 - Oct 14th, 2005, 11:31pm
 
Possibly.. though I've never looked at the processing source before, so it may well be significantly beyond me.

But I'll have a look, and see if I can work out where on earth I shoudl even start looking.
Re: P3D fill and texture
Reply #5 - Oct 16th, 2005, 1:51am
 
Success!

And without needing to edit the processing source.

I realised that if I work out what world-coordinates turn into in z-buffer values, I could just scale the fog colouring as a ratio between the near and far z-buffer depths, and do a per-pixel fogging that way.

Unfortunately, this does require drawing to screen for a single frame when set-up. If anyone knows a way to convert world coordinate distance from camera into zbuffer values, this part could be skipped. I've looked through the source, and can't quite work out how it's calculated.

Anyway, without further ado, here's the code:

Code:
class fog
{
float near, far;
PGraphics3 pg3;
fog(float worldnear, float worldfar,PGraphics pg)
{
pg3=(PGraphics3)pg;
pushMatrix();
camera(0,0,0,0,0,1,0,1,0);
beginShape(QUADS);
{
vertex(-100,-100,worldnear);
vertex(100,-100,worldnear);
vertex(100,100,worldnear);
vertex(-100,100,worldnear);
}
endShape();
updatePixels();
near=pg3.zbuffer[width/2+((height/2)*width)];
background(0);
beginShape(QUADS);
{
vertex(-100,-100,worldfar);
vertex(100,-100,worldfar);
vertex(100,100,worldfar);
vertex(-100,100,worldfar);
}
endShape();
updatePixels();
far=pg3.zbuffer[width/2+((height/2)*width)];
popMatrix();
camera();
background(0);
if(near == MAX_FLOAT || far == MAX_FLOAT)
{
throw new RuntimeException("Near and Far must be positive values, and not clipped");
}
println("Near:" +worldnear+"="+near);
println("Far:" +worldfar+"="+far);
}

float getDepth(float zval)
{
if(zval < near)
return 0;
else if(zval > far)
return 1;
else
{
return (zval-near)/(far-near);
}
}

void doFog(color mistColour)
{
loadPixels();
for(int i=0;i<pixels.length;i++)
{
float a=this.getDepth(pg3.zbuffer[i]);
pixels[i]=cblend(pixels[i],mistColour,a);
}
updatePixels();

}
}

color cblend(color a, color b, float ratio)
{
if(ratio<=0)
return a;
if(ratio>=1)
return b;

float r=red(a)*(1-ratio)+red(b)*ratio;
float g=green(a)*(1-ratio)+green(b)*ratio;
float bl=blue(a)*(1-ratio)+blue(b)*ratio;
return color(r,g,bl);
}


used like:

Code:
color mist;
fog f;

void setup()
{
size(400,400,P3D);
f=new fog(400,500,g);
mist=color(128,128,255);
noStroke();
}

void draw()
{
background(0);
fill(255,255,255);
beginShape(TRIANGLES);
vertex(100,100,0);
vertex(300,100,-100);
vertex(300,300,-300);
endShape();
f.doFog(mist);
}


(note the discrpency between fog depth, and object z-coordinate, this is because the camera isn't at 0,0,0, but  0,0,-(something) to mean things at z=0 are on screen)
Page Index Toggle Pages: 1