Horde3D

Next-Generation Graphics Engine
It is currently 24.11.2024, 20:13

All times are UTC + 1 hour




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Basic Toon shading
PostPosted: 23.05.2012, 12:48 
Offline

Joined: 23.05.2012, 12:36
Posts: 1
I am trying to get some basic toon shading working, I am using the game engine + editor.

I wrote my own pipeline :

Code:
<Pipeline>
    <CommandQueue>
   
        <Stage id="FirstStage" link="globalSettings.material.xml">
            <ClearTarget depthBuf="true" colBuf0="true" />
            <DrawGeometry context="AMBIENT" class="~TRANSLUCTENT" />
        </Stage>
   <Stage id="Overlays">
      <DrawOverlays context="OVERLAY" />
   </Stage>
    </CommandQueue>
</Pipeline>


and this is my shader :

Code:
[[FX]]
sampler2D albedoMap;

// Contexts
context AMBIENT
{
   VertexShader = compile GLSL VS_OVERLAY;
   PixelShader = compile GLSL FS_OVERLAY;
}

[[VS_OVERLAY]]

#include "shaders/utilityLib/vertCommon.glsl"
#include "shaders/utilityLib/vertSkinning.glsl"

uniform mat4 viewProjMat;
uniform vec3 viewerPos;
attribute vec3 vertPos;
attribute vec2 texCoords0;
attribute vec3 normal;
varying vec4 pos, vsPos;
varying vec2 texCoords;
varying vec3 tsbNormal;

void main( void )
{
   mat4 skinningMat = calcSkinningMat();
   mat3 skinningMatVec = getSkinningMatVec( skinningMat );
   pos = calcWorldPos( skinPos( vec4( vertPos, 1.0 ), skinningMat ) );
   vsPos = calcViewPos( pos );
   tsbNormal = normal;
   texCoords = texCoords0;
   gl_Position = viewProjMat * pos;
}

[[FS_OVERLAY]]
uniform sampler2D albedoMap;
varying vec2 texCoords;
varying vec3 tsbNormal;


void main( void )
{
   //Flip coords for glsl
   vec3 newCoords = vec3( texCoords, 0 );
   newCoords.t *= -1.0;
   //Calculate shading
   vec3 textColour = texture2D( albedoMap, newCoords ).rgb;
   float light = min(dot(tsbNormal, vec3(1,0,0)), 1);
   //Thresholds for cell shading
   if(light < 0.3)
      light = 0.3;
   else if(light < 0.7)
      light = 0.7;
   else
      light = 1;
   gl_FragColor.rgb = textColour * light;
}


Currently I am trying to use a global lightning direction but that doesn't seem to work, the lightning always stays on the same side of the model. Lets say I have a model who I light from the back and I am looking at the front, then its all oke since the front is dark and the back is light, then if I turn the model 180 degrees and the back faces the camera its still light instead of going dark as it should be.

Anyone got any clue why this is happening / how to fix it.


Top
 Profile  
Reply with quote  
 Post subject: Re: Basic Toon shading
PostPosted: 23.05.2012, 14:06 
Offline

Joined: 26.09.2011, 23:56
Posts: 14
Location: Augsburg
Hi!

In this line vec3(1.0, 0.0, 0.0) should represent your light direction?
Code:
float light = min(dot(tsbNormal, vec3(1,0,0)), 1);


The problem is, that dot can also result negative values. Normalizing your normal is also a good idea.

Quote:
vec3 normal = normalize(tsbNormal);
vec3 lightDir = vec3(1.0, 0.0, 0.0);
float light = max(0.0, dot(lightDir, normal));


Then I also suggest to modify your pipeline in the way, that you don't use the Overlay-Context. I don't know if this leads to some problems too. You can for example look at the forward pipeline how this could be done.

Hope this fixes your problem :)


Top
 Profile  
Reply with quote  
 Post subject: Re: Basic Toon shading
PostPosted: 24.05.2012, 00:22 
Offline

Joined: 15.02.2009, 02:13
Posts: 161
Location: Sydney Australia
Hi quincy18,

Nice work with the toon shader, about the global lighting direction I'm guessing it's some uniform declaration in globalSettings.material.xml. You'll need to expose this uniform in your shader by the looks of it to whatever it is called, and also pass it as a varying to the fragment shader so when you do your light calculation in that dot it uses your uniform or varying vec3.

Also instead of doing branching which can cause cache misses to get your toon shade curve I'd recommend perhaps use a lookup table (ie a sampler2d of a gradient ramp that matches what you're doing with the if statements) and multiply it with your 'float light' in the fragment stage.

For more of a speed gain (and this is what Horde should be doing by default) is to move the flip coords from the fragment program to the vertex program so it doesn't do an unneeded dependent texture fetch, but that's up to you.

Hope this helps!

_________________
-Alex
Website


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group