thanks for the test case, i’m on it
After a lot of mucking around, I solved this by setting the background viewport to write to the same buffer as the main viewport with the filterprocessor.
If added after the FilterPostProcessor (so that the reshape method is called later), this works:
[java]
viewPort.addProcessor(new SceneProcessor()
{
public boolean initialised;
public void initialize(RenderManager rm, ViewPort vp)
{
reshape(vp, vp.getCamera().getWidth(), vp.getCamera().getHeight());
initialised = true;
}
public void reshape(ViewPort vp, int w, int h)
{
backgroundViewPort.setOutputFrameBuffer(viewPort.getOutputFrameBuffer());
}
public boolean isInitialized()
{
return initialised;
}
public void preFrame(float tpf)
{
}
([empty methods omitted)
});
[/java]
Otherwise, if the FilterPostProcessor is added later, this is necessary:
[java]
[java]
viewPort.addProcessor(new SceneProcessor()
{
public boolean initialised;
public void initialize(RenderManager rm, ViewPort vp)
{
initialised = true;
}
public void reshape(ViewPort vp, int w, int h)
{
}
public boolean isInitialized()
{
return initialised;
}
public void preFrame(float tpf)
{
backgroundViewPort.setOutputFrameBuffer(viewPort.getOutputFrameBuffer());
}
([empty methods omitted)
});
[/java]
This solves my case, which is to apply the filter to both the background and main viewports.
However, if someone wanted to apply the filter to only the main viewport, the original problem would remain.
-davidc
mhh wait…ok…this can’t work
// Set the main viewport to not clear colour buffer
viewPort.setClearEnabled(true);
viewPort.setClearFlags(false, true, true);
this causes the issue…you don’t clear the color.
besides the filter is applied to one viewport (here on the main viewport) and is rendered on a full screen quad.
That’s why your background viewport does not render and the “not clearing color” thing makes this trailing effects.
Filters were not designed with this in mind and would need a complete revision in the architecture to make this work, so your options are :
- not use a gradient fixed background (but it’s a bit drastic :p)
- not use Filter (drastic too)
- Find a way to make your fixed background with one viewport.
for this a combination of a quad in the sky bucket and a shader would do the trick I guess.
Oh did not see your post before mine.
Well you should use this instead :
Create a normal scene and just use that as a sky
Quad q=new Quad(1, 1);
Geometry geom=new Geometry(“bg”, q);
Material bgMaterial = new Material(assetManager, “Shaders/fixedBg/Gradient.j3md”);
geom.setMaterial(bgMaterial);
geom.setQueueBucket(RenderQueue.Bucket.Sky);
geom.setCullHint(Spatial.CullHint.Never);
rootNode.attachChild(geom);
the shaders and matdef associated are like this :
Gradient.j3md
MaterialDef Gradient {
MaterialParameters {
}
Technique {
VertexShader GLSL100: Shaders/fixedBg/Gradient.vert
FragmentShader GLSL100: Shaders/fixedBg/Gradient.frag
WorldParameters {
WorldViewProjectionMatrix
}
}
Technique FixedFunc {
}
}
Gradient.vert
uniform mat4 g_WorldViewProjectionMatrix;
attribute vec4 inPosition;
varying vec4 pos;
void main() {
pos = inPosition* 2.0 - 1.0;
gl_Position = pos;
}
Gradient.frag
varying vec4 pos;
void main() {
gl_FragColor = vec4(pos);
}
this will be more efficient and lot more simple.
Thanks, I’ll try that soon. It’ll need some development as I have various things in the background. For now I have the basic effect working and I need to finish my 7-day prototype in time
-davidc
Hello,
can someone please explain what the codeline
pos = inPosition* 2.0 - 1.0;
does? inPosition is a vec4. How can a vec4 object be multiplied by a figure and subtract 1.0 to be stored in another vec4 object? Does glsl automatically convert the objects? Moreover I do not understand what this multiplication and subtraction is good for. I tried to implement linear gradient and have written following shaders…
JME
[java]
MaterialDef Gradient {
MaterialParameters {
Color m_FirstColor
Color m_SecondColor
}
Technique {
VertexShader GLSL100: at/netcrystals/praxiteles/jme3/shaders/Gradient.vert
FragmentShader GLSL100: at/netcrystals/praxiteles/jme3/shaders/Gradient.frag
WorldParameters {
WorldViewProjectionMatrix
}
Defines {
FIRSTCOLOR : m_FirstColor
SECONDCOLOR : m_SecondColor
}
}
Technique FixedFunc {
}
}
[/java]
Vertex Shader
[java]
uniform mat4 g_WorldViewProjectionMatrix;
uniform vec4 m_FirstColor;
uniform vec4 m_SecondColor;
attribute vec4 inPosition;
varying vec4 pos;
varying vec4 color1;
varying vec4 color2;
void main() {
color1=m_FirstColor;
color2=m_SecondColor;
pos=2.0*inPosition-1.0;
gl_Position=pos;
}
[/java]
Fragment Shader
[java]
varying vec4 pos;
varying vec4 color1;
varying vec4 color2;
void main() {
gl_FragColor = (abs(1.0-pos.x)color1+pos.xcolor2);
}
[/java]
but the gradient is not very smooth.
Thanks a lot.
Regards,
Equi
Hello,
can someone please explain what the codeline
pos = inPosition* 2.0 – 1.0;
I didnt check that code but that line normally means [0, 1] -> [-1, 1] (and I think that orig value must be 0.0 - 1.0 (normalized vector in this case))
why dont u use unshaded material that has gradient texture ?
does?
it transforms the inPosition value from a 0 to 1 space to a -1 to 1 space.
that's a cheap way of projecting a 1 x 1 quad to the entire screen.
inPosition is a vec4. How can a vec4 object be multiplied by a figure and subtract 1.0 to be stored in another vec4 object? Does glsl automatically convert the objects?
Yes it's automatically converted, that's glsl magic...or at least the drivers of your graphic card magic. I think it's wrong to do it because it may fail on some graphic cards. the correct way to do it is
pos = inPosition * vec4(2.0) – vec4(1.0);
I did it like this because i'm lazy.
Moreover I do not understand what this multiplication and subtraction is good for. I tried to implement linear gradient and have written following shaders…
You have understand what's the vertex shader's main job : project the 3D world coordinates of the vertex to projection space. projection space is a 2D space going from -1 to 1 in the x and y coordinates. x goes along the width of the screen (actually the display window) from left to right and y goes along the height from bottom to top.
so...here i want my quad to be displayed fullscreen, its 3D coordinates goes from 0 to 1 on x and y, what ever z. I need 0 to be -1 an 1 to be 1
hence the * 2 - 1.
Also for your gradient, let's say you want a bottom to top gradient, use
float factor = pos.y * 0.5 + 0.5 //inverse transformation as the * 2 - 1
gl_FragColor = mix(color1,color2,factor);
mix linearly interpolates the values from color1 to color2 according to factor (factor must go from 0 to 1, hence the inverse transform)
hope that helps
Hello,
thanks a lot. This is the missing link. Project space is [-1,1]x[-1,1] and not [0,1]x[0,1]. this helps a lot.
However, glsl is rather strange
Regards,
Equi