Shadows, Shaders, DisplayLists?

Hi,

Can somebody please provide some more information on the following features in relation to the current Xith code

Shadows - I know there is some work being done on this, I would like to know a bit more about how it works (or doesn’t work) in the current version, where should I start if I wanna start playing with this feature (where the code is and how is it supposed to work).

Pixel / Vertex Shaders - I have seen some code in CoolDude’s demos, is there any addition documentation, planned development, design ideas, or any kind of specific information on how this currently works (supposed to work). I am specifically interested in Per pixel lighting and using the shading language for materials.

Display Lists - Is there any documentation, examples, planned deveopment, etc…

Thanks

Don’t know. Ask Amos. I haven’t used shadows so far.

We also have GLSL shaders. And we have both vertex and pixel shaders. But I haven’t worked with them so far. So I can only tell you, they are there.

Display Lists are used, when a Shape3D is of the Type STATIC (see the setType() method or the specific constructor) or another not-DYNAMIC type. See the JavaDoc for more details. DisplayLists are not fully used. They’re planned to be used in a larger extend. But it won’t hit the API; just internal changes resulting in speed-ups.

Marvin

I have a zip of a Java3D implementation of shadows done by javacooldude. I can post it as a starting place

[quote]I have a zip of a Java3D implementation of shadows done by javacooldude. I can post it as a starting place
[/quote]
That would be great.

Also if somebody is familiar how shadows are supposed to work in Xith please post some info.

Cheers

Well that’s what’s problematic : it was David Yazel who implemented them and he has gone so we have to take over his work. But I said I was gonna work on it…

AFAIK, It works with several render passes, for an object to have a shadow, first an Occluder must be computed (user-side : set shape3d.setIsOccluder(true) first) then some tricky rendering stuff is done and tadaa it works… Now that’s roughly that but in maybe 20 minutes I’ll be able again to do some Java stuff (I’m reinstalling my PC)

Hahahaha, wish it was that simple :-\

[quote]it was David Yazel who implemented them and he has gone so we have to take over his work. But I said I was gonna work on it…
[/quote]
I am guessing (but might be completely wrong) it should go something like this

The occluders have to be created / maintaned properly… based on some proxy shape volume
The shadow geometry has to be created using projected rays / occluder intersections…
Shadow geometry is rendered in a sepparate rendering pass (stencil buffer?)…
Shadow rendering output is composited over the image…

Now where would this be in current Xith code?

why,in ShadowAtomPeer, I suppose…

DarkProphet, I almost knew how it works, but had no time to explain further…

Hi,

I was able to fix the shadows when I change the following methods too look like this

 private final void drawObjectShadow(GL gl, Occluder object, Point3f lightPosition)
    {
        object.getLocalToVworld().getOpengl(openGLProjMatrix);

        gl.glPushMatrix();
       
        gl.glMultMatrixf(openGLProjMatrix, 0);
        
        gl.glDisableClientState(GL.GL_COLOR_ARRAY);
        gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
        gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
        gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
        
        object.getBuffer().getCoordinateData().getFloatBuffer().rewind();
        gl.glVertexPointer(3, GL.GL_FLOAT, 0, object.getBuffer().getCoordinateData().getFloatBuffer());
        gl.glDrawArrays(GL.GL_TRIANGLES, 0, object.getBuffer().getValidVertexCount());
        addTriangles( object.getBuffer().getValidVertexCount() / 3 );
        gl.glPopMatrix();
    }
    
    /**
     * draws the shadow volumns in the render bin
     * 
     * @param bin
     */
    protected final void drawShadows(GL gl, ShadowBin bin)
    {
        //ProfileTimer.startProfile("CanvasPeerImpl::drawShadows");
        final int FULLMASK = 0xffffffff;
        final int STENCIL_VAL = 128;
        
        // determine edges
        
        for (int i = 0; i < bin.size(); i++)
        {
             bin.getOccluder(i).determineVisibleEdges( bin.getLightSource() );
        }
        
        gl.glDisable(GL.GL_LIGHTING); // Turn Off Lighting
        
        gl.glEnable(GL.GL_CULL_FACE);
        gl.glCullFace(GL.GL_BACK);
        
        gl.glDepthMask(false); // Turn Off Writing To The Depth-Buffer
        gl.glDepthFunc(GL.GL_LEQUAL);
        
        gl.glEnable(GL.GL_STENCIL_TEST); // Turn On Stencil Buffer Testing
        gl.glColorMask(false, false, false, false); // Don't Draw Into The Colour Buffer
        gl.glStencilFunc(GL.GL_ALWAYS, 1, 0xffffffff);
        gl.glFrontFace(GL.GL_CCW);
        
        // First Pass. Increase Stencil Value In The Shadow
        
        gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_INCR);
        
        for (int i = 0; i < bin.size(); i++)
        {
             drawObjectShadow( gl, bin.getOccluder(i), bin.getLightSource() );
        }
        
        // Second Pass. Decrease Stencil Value In The Shadow
    
        gl.glFrontFace(GL.GL_CW);
        gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_DECR);
        
        gl.glColor3f(0f, 0f, 0f);
        for (int i = 0; i < bin.size(); i++)
        {
             drawObjectShadow( gl, bin.getOccluder(i), bin.getLightSource() );
        }
        
        gl.glFrontFace(GL.GL_CCW);
        gl.glColorMask(true, true, true, true); // Enable Rendering To Colour Buffer For All Components
        
        // Draw A Shadowing Rectangle Covering The Entire Screen
        gl.glColor4f(0.0f, 0.0f, 0.0f, 0.2f);
        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
        gl.glStencilFunc(GL.GL_NOTEQUAL, 0, 0xffffffff);
        gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP);
        gl.glPushMatrix();
        gl.glLoadIdentity();
        gl.glBegin(GL.GL_TRIANGLE_STRIP);
        gl.glVertex3f(-1f, 1f, -0.20f);
        gl.glVertex3f(-1f, -1f, -0.20f);
        gl.glVertex3f(1f, 1f, -0.20f);
        gl.glVertex3f(1f, -1f, -0.20f);
        gl.glEnd();
        gl.glPopMatrix();
        gl.glDisable(GL.GL_BLEND);
        gl.glDepthFunc(GL.GL_LEQUAL);
        gl.glDepthMask(true);
        gl.glEnable(GL.GL_LIGHTING);
        gl.glDisable(GL.GL_STENCIL_TEST);
        gl.glShadeModel(GL.GL_SMOOTH);
    }

Cheers

Vlad

Man, just tell me your SF.net account name (or create one) and I’ll grant you Dev access on xith3d & xith-tk.

2 hundreds thanks :slight_smile: (haven’t tested yet but trusting you).

I have committed the Shadows fix. How can I see, if it works now?

Marvin

Setup a scene with let’s say a plane at 0 in Y and a cube above it. Now the cube you need to make an occluder by using setIsOccluder(true). I think you also need to add a point light (-1000,1100,1100 seems to be a good location for it), and set up the appearances that have materials defined. In my test I used the following settings for light:

PointLight light = new PointLight(true, new Color3f(0.5f, 0.5f, 1),new Point3f(-1000,1100,1100), new Vector3f());

and the following for material:

mat.setAmbientColor(0.25f,0.25f,0.25f);
mat.setShininess(0.75f);

Now it is possible that you can actually get the shadows to appear without the light source and material defined I just haven’t tested that far. From the code it looks like the actuall lights that are in the scene are not used for the shadow calculations. There is a hard coded light location at -10000, 10000, 10000 or something like that, that is used for all the shadow volume projections. The improvement here would be to use the actual light node and their locations in space to calculate the shadow volumes.

Thanks. I will check it out.

Marvin