www.jpct.net

jPCT - a 3d engine for Java => Support => Topic started by: Geemili on June 25, 2012, 06:34:38 pm

Title: Shaders
Post by: Geemili on June 25, 2012, 06:34:38 pm
Hi, this is my first time venturing into 3D and am trying to use shaders. Specifically, outlining and cel-shading. I have made the cel-shading following some tutorials, but cannot figure out the outlining.

I have found two ways of doing outlining, the first is editing the rendered image and applying a sobel filter or another of similar effect. When I tried doing this, I didn't get it to work, but it required me to use FrameBuffer.getPixels(), which seems to be slow. Also, my fault here, I don't understand the images format, at least, not enough to change into a 2d array of colors.

The second way is to first draw a wireframe version of the current object with its front faces culled and the rendering it regularly. This one is supposedly easier, but I don't know where to place the code.

Also, less important (In My Opinion) is how to get the lightVec variable to glsl. I saw it used in the shader example (http://www.jpct.net/wiki/index.php/Shaders) and put:
Code: [Select]
varying vec3 lightVecinto the .glsl, but it did not seem to work.

Thank for reading my post. I am sorry for any ignorance, but I feel impatient to get this done. Ask if you need code.
Title: Re: Shaders
Post by: Thomas. on June 25, 2012, 06:52:51 pm
For variables in shader you have to use uniforms. Varying (http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/varying.php) is used to interpolation variables from vertex shader to fragment shader.
So in application you should use "shader.setUniform("lightVec", ...);" and in shader "uniform vec3 lightVec;"...
Title: Re: Shaders
Post by: EgonOlsen on June 25, 2012, 08:01:44 pm
The second way is to first draw a wireframe version of the current object with its front faces culled and the rendering it regularly. This one is supposedly easier, but I don't know where to place the code.
Can you explain this in a little more detail. I'm not 100% sure that i get the idea...
Title: Re: Shaders
Post by: Geemili on June 25, 2012, 08:08:33 pm
Sorry, I'm not the best at explaining. Here (http://www.cse.unr.edu/~mahsman/courses/cs791a/) is a link that should help. You'll have to scroll down a bit though, it's in section 3.4.
Title: Re: Shaders
Post by: EgonOlsen on June 25, 2012, 08:44:42 pm
I see...to do this with jPCT's wireframe rendering mode, you have to implement a simple IRenderHook to tweak it, because by default, jPCT uses a line width of 1 and no culling in wireframe mode. Here's a little example....however, i don't really think that the effect looks that great in motion...anyway...

Code: [Select]
import java.awt.Color;

import org.lwjgl.opengl.GL11;

import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderHook;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Loader;
import com.threed.jpct.Object3D;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;

public class Outlines {

private World world;

private FrameBuffer buffer;

private Object3D box;

public static void main(String[] args) throws Exception {
new Outlines().loop();
}

public Outlines() throws Exception {
world = new World();
world.setAmbientLight(255, 255, 255);

TextureManager.getInstance().addTexture("box", new Texture("box.jpg"));

box = Loader.loadASC("beethoven.asc", 50f, false);
box.setTexture("box");
box.rotateX((float) Math.PI / 2f);
box.rotateMesh();
box.clearRotation();
box.calcTextureWrapSpherical();
box.build();
box.compile();
world.addObject(box);

world.getCamera().setPosition(50, 20, -5);
world.getCamera().lookAt(box.getTransformedCenter());
}

private void loop() throws Exception {
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_GL_AA_2X);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);

Outliner ol=new Outliner();

while (!org.lwjgl.opengl.Display.isCloseRequested()) {
box.rotateY(0.01f);
box.rotateX(0.01f);
buffer.clear(java.awt.Color.BLUE);


box.invertCulling(true);
box.setRenderHook(ol);
world.renderScene(buffer);
world.drawWireframe(buffer, Color.BLACK);
box.setRenderHook(null);

box.invertCulling(false);
world.renderScene(buffer);
world.draw(buffer);

buffer.update();
buffer.displayGLOnly();

Thread.sleep(10);
}
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
System.exit(0);
}

private static class Outliner implements IRenderHook {

@Override
public void beforeRendering(int polyID) {
GL11.glLineWidth(5);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_CULL_FACE);
}

@Override
public void afterRendering(int polyID) {
GL11.glLineWidth(1);
}

@Override
public void setCurrentObject3D(Object3D obj) {
// TODO Auto-generated method stub
}

@Override
public void setTransparency(float transparency) {
// TODO Auto-generated method stub

}

@Override
public void onDispose() {
// TODO Auto-generated method stub

}

@Override
public boolean repeatRendering() {
// TODO Auto-generated method stub
return false;
}

@Override
public void clear() {
// TODO Auto-generated method stub

}

}
}

Title: Re: Shaders
Post by: Geemili on June 25, 2012, 09:27:28 pm
Thank you! It works perfectly!  ;D

The only major change that will need to be done is something that does it automatically for each object, which shouldn't be so bad. Thanks again!