Search Home Members Contacts
About Us
Products
Downloads
Community
Support
Pages: [1]
  Print  
Author Topic: Actor Custom Shader  (Read 1173 times)
arnienet
Customers
Community Member
*****
Posts: 263


WWW
« on: August 05, 2010, 04:32:46 PM »

Hi,

I've just been doing some trials with TV3D, landscape bump mapping and actor shadows. bump mapping and projected actor shadows are working fine, I just need to finish depth tested shadows, but thought I would first test out actor custom shaders as I will need actors to receive shadows as well as cast them.

Both TV3D's feature list and the wiki's description say that TV3D supports custom actor shaders, and I assume the TV3D engine must use an internal actor shader for GPU actor animations (please correct me if I'm wrong). I have only managed to find 2 actor shaders for TV3D, the one I'm using downloaded from:

http://www.truevision3d.com/downloads/uploads/CustomActorShader.fx

and a bump mapped derivation from an unknown source, and a semi relevant post on the forum at:

http://www.truevision3d.com/forums/shader_development/weird_custom_actor_shader_from_wiki-t17770.0.html;msg121798#msg121798

The project all works well until I apply this shader to the actor object, then it is no longer drawn in the scene or at least the camera fustrum. I have also applied SetActorMode(CONST_TV_ACTORMODE.TV_ACTORMODE_SHADER), and checked the models I've tried for any faults (they do have more than 1 group, defined by individual materials in the X file format). I have also tried it with a model with just 1 material group.

In the absence of any further information, can anyone tell me if I'm missing anything, or could it be a bug. Does the Dev team have any working samples they could share?

There is a video of the problem at:

http://www.dawn-world.com/Bugs/ActorShader/Bug_ActorShader.html

and here's a screen shot:




Many thanks.
« Last Edit: August 05, 2010, 07:28:59 PM by arnienet » Logged

Total Dev time = 50% to code, 50% to test, 50% to find errors, 50% to fix, that's why it takes twice as long.

Dawn World MMO
Dimple
Community Member
*
Posts: 580


« Reply #1 on: August 05, 2010, 07:35:02 PM »

 Smiley

arnienet,


Try this version of the custom actor shader made in 2009. 

See this post: This is from reply # 15 It might work, is it that the problem is the texture isn't loading?

http://www.truevision3d.com/forums/shader_development/shader_changes_actor_orientation-t19107.0.html


Code:
///////////////////////////////////////////////////
// Example file for custom actor shaders using GPU
///////////////////////////////////////////////////

//
// Reminder : Custom Shaders are possible via CPU actor mode
//       but they are quite slow because it must transform every vertex of the actor on CPU
//
// Here we will use a faster technique made possible recently for TVActor
//
//

// The important thing is the vertex structure used by TV.


// here is the non bumpmapped version, so there is no Tangent nor Binormal vector :
struct VS_INPUT_NONBUMP
{
float3 position : POSITION ;    // vertex position in the default pose
    float3 normal : NORMAL;   // vertex normal in the default pose
    float4 blendindices : BLENDINDICES;  // indices of the 4 bone indices used in the bone matrix array
    float4 blendweights : BLENDWEIGHT; // weights of each bone.
    float2 tex1 : TEXCOORD0; // standard texture coordinates.
};

// here is the bumpmapped version, with tangents :
struct VS_INPUT_BUMP
{
float3 position : POSITION;
float3 normal : NORMAL; //
float3 tangent : TANGENT; //  this forms the tangent matrix.
        float3 binormal : BINORMAL; //
float4 blendindices : BLENDINDICES;
float4 blendweights : BLENDWEIGHT;
float2 tex1 : TEXCOORD0;
};


// another important thing is how are stored the matrices.

// Warning : there are two possible versions of the skinning in the TVActor
// - a vertex shader 1.1 version, allowing max 16 bones in a draw call.
// - a vertex shader 2.0 version, allowing max 52 bones in a draw call.
//    These are constant values, you can't change them.

// the easiest way is to work only with VS2.0 vertex shader mode and always allocate 52 bone matrices.

// a matrix here is only using 3 rows (float4x3) so we will use an array of float4x3, it MUST have the semantic BONES
float4x3 boneMatrices[52] : BONES;

// here is the number of bones used per vertex
int iNumBonePerVertex : BONESPERVERTEX; 


// a simple world matrix is used when there is no bone influence (it must have the semantic WORLD);
float4x4 worldMat : WORLD;

// usual viewprojection to complete the transformation
float4x4 ViewProj : VIEWPROJECTION;

 
float3 dirLightDir = (0.0f,1.0f,0.0f); //: LIGHTDIR;  this is broken :so you'll have to set it from TV
float3 materialEmissive : EMISSIVE;
float3 materialAmbient : AMBIENT;
float4 materialDiffuse : DIFFUSE;
float3 materialSpecular : SPECULAR;
float materialPower : SPECULARPOWER;
float3 dirLightColor = (1,1,1); // : LIGHTDIR0_COLOR; also broken, set it manualy
float3 viewdir;// : VIEWPOS; again.. borked.. you'll need to set it every frame :\par
float2 scale = (1,1);
 
float glowpower = 3; //this changes how much backglow you have
float4 glowcolor = (1,1,1,1);//and its color
 
// here is the standard skinning function of TV to skin the position and normal
// there must be 5 versions : one for each case (0 bone blending, 1 bone blending, 2 bones blending, .. ,4 bones blending)
void TransPositionNormal( uniform int iNumBones, float4 modelPos, float3 modelNorm,
                   float4 boneWeights, float4 fBoneIndices, out float3 pos, out float3 norm)
{

if(iNumBones == 0)
{
         pos = mul(modelPos, worldMat);
norm = mul(modelNorm, (float3x3)worldMat);
}
else
{
        int4 ibone = D3DCOLORtoUBYTE4(fBoneIndices);
       int   IndexArray[4]        = (int[4])ibone;

pos = 0;
norm = 0;
float lastweight = 0.0f;
for(int i = 0; i < iNumBones - 1; i++)
{
          float4x3 mat = boneMatrices[IndexArray[i]];
  lastweight = lastweight + boneWeights[i];
  pos += mul(modelPos, mat) *  boneWeights[i];
  norm += mul(modelNorm, (float3x3)mat ) *  boneWeights[i];
}

lastweight = 1 - lastweight;
    float4x3 mat = boneMatrices[IndexArray[iNumBones-1]];
        pos += mul(modelPos, mat) * lastweight;
norm += mul(modelNorm, (float3x3)mat ) *  lastweight;
}
return;




// simple sample that does nothing fancy.
struct VS_OUTPUT
{
   float4 position : POSITION;
   float4 diffuse : COLOR0;
   float2 tex : TEXCOORD0;
   float3 ldir : TEXCOORD1;
   float3 normal : TEXCOORD2;
   float3 view : TEXCOORD3;
   float3 dlc : TEXCOORD4;
};

VS_OUTPUT ActorShader(uniform int iNumBones, VS_INPUT_NONBUMP inp)
{
   VS_OUTPUT o = (VS_OUTPUT)0;
   float3 pos, norm;
   
   // use our skinning method
   TransPositionNormal( iNumBones, float4(inp.position, 1.0f), inp.normal, inp.blendweights, inp.blendindices, pos, norm);
   
   // then let's transform the position into clip space using view proj matrix
   float4 p = mul(float4(pos,1.0f), ViewProj);
   o.position = p;
   float3 n = normalize(norm);
   o.normal = n;
   o.tex = inp.tex1 * scale;
   o.view = viewdir;
   o.ldir = normalize(dirLightDir);
   o.diffuse = float4(normalize(dirLightDir), 1.0f);  // some weird const lighting computation
   return o;
}

texture texTexture : TEXTURE0; // tv will automatically set current texture to TEXTURE0
sampler sampTexture = sampler_state {Texture = <texTexture>;};

// simple pixel shader that just output the pixel
float4 ActorPixelShader(VS_OUTPUT inp) : COLOR0
{
   float3 light = normalize(-inp.ldir);
   float3 lcolor =  saturate(inp.dlc * (1, 1, 1));
   float3 view = normalize(inp.view);
   float3 inview = normalize(-view);
   float2 tcoor = inp.tex;
   float4 tColor = tex2D(sampTexture, tcoor);
   float3 ambient =  materialAmbient;
   float3 normish = normalize(inp.normal);
   float3 smooth = lerp(light,normish,0.3f);
   float3 halfway = lerp(light, view,0.3f);
   float3 specular = pow(saturate(dot(normish, halfway)), materialPower) * materialSpecular;
   float3 emissive = materialEmissive;
 
   float3 glowy = lerp(inview, normish,0.3f);
   float3 glow = pow(saturate(dot(glowy / 1.2f, inview)), glowpower) * glowcolor.rgb;
 
   float3 diffuse = pow(saturate(dot(smooth , light)) * materialDiffuse.rgb, 1.5);
 
   float3 c = (saturate(ambient + diffuse ) * tColor.rgb + specular) * lcolor + emissive + (glow * 0.8f);
 
   float alpha = materialDiffuse.a * tColor.a;
   return float4(c, alpha);
}

VertexShader VSArray[5] = { compile vs_2_0 ActorShader(0),
   compile vs_2_0 ActorShader(1),
   compile vs_2_0 ActorShader(2),
       compile vs_2_0 ActorShader(3),
   compile vs_2_0 ActorShader(4)
  };




technique ActShader
{
    pass pass0
    {
       VertexShader = ( VSArray[iNumBonePerVertex] );
       PixelShader = compile ps_2_0 ActorPixelShader();
    }
}

Logged

Using VB.NET, TV3D 6.5, VISTA
~~~~~~~~~~~~~~~~~~~~~~~

"Know how to ask. There is nothing more difficult for some people, nor for others, easier."

- Baltasar Gracian
arnienet
Customers
Community Member
*****
Posts: 263


WWW
« Reply #2 on: August 06, 2010, 12:33:51 PM »

Thanks Dimple,

The shader you posted was the 2nd one (I forgot exactly where I got it from), it didn't work in my main project, but as I've had actor related issues with it before, I decided to set up a basic test project. I also followed the forum link you gave and copied and pasted the code that was reported working into my shader file in the test project with much better results.

The original problem was the actor just wasn't been drawn in the view fustrum, I had even previously coded float4(1,1,1,1) for the output of the pixel shader to get some output, with no result (looked like a vertex translation problem possibly). Anyway in the test app, it looks like the shader has been adapted from another engine/renderer and with some tweaking, I'm getting a correctly shaded, oriented and animated actor through the shader, nice Smiley There's still no texture, and I suspect the shader will need a bit of tweaking for TV3D.

Looking at the shader code the semantics may not map correctly and so far the best results have been from mapping:

float3 viewdir: LIGHTDIR; not float3 viewdir: VIEWPOS;

although the variable name 'viewdir' may be misleading in this case, I have however got a good base to work from now, so thanks again for the very useful input. Here's an image of the output with this mapping, much better Smiley




« Last Edit: August 06, 2010, 01:27:34 PM by arnienet » Logged

Total Dev time = 50% to code, 50% to test, 50% to find errors, 50% to fix, that's why it takes twice as long.

Dawn World MMO
Dimple
Community Member
*
Posts: 580


« Reply #3 on: August 06, 2010, 05:41:03 PM »

 Smiley

Your welcome arnienet,

I'm glad it helped.  I've got a long way to go yet in having a good understanding of shaders. Let alone how to use them with TV3D and get them to work consistently.  So, If you get this problem sorted out, please let us know how you did it. 
Logged

Using VB.NET, TV3D 6.5, VISTA
~~~~~~~~~~~~~~~~~~~~~~~

"Know how to ask. There is nothing more difficult for some people, nor for others, easier."

- Baltasar Gracian
arnienet
Customers
Community Member
*****
Posts: 263


WWW
« Reply #4 on: August 06, 2010, 07:24:18 PM »

Yes, for sure,

I know what you mean, I've spent months working out and optimising various shaders for the project, Zak's examples have been very useful. There does seem to be a specific way to use shaders with TV3D. When I get the actor shader up and running correctly, I intend to post a VB.net demo project on the forum by way of a thanks to community and dev team for everyone's help so far Smiley

I've actually been tweaking the shader a bit more and got the texture rendering now. It's not perfect, but it's a good step in the right direction, here's an image:

« Last Edit: August 06, 2010, 07:43:57 PM by arnienet » Logged

Total Dev time = 50% to code, 50% to test, 50% to find errors, 50% to fix, that's why it takes twice as long.

Dawn World MMO
Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.3 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks