3D Rad - Free 3D game maker - Forum

This forum is now archived!

This forum is locked, and is a read-only version. A new community-ran forum can be found at classdev.net

News:

The 3DRad community can be found at classdev.net.

Pages: [1]

Author Topic: Shader request  (Read 3061 times)

« on: January 12, 2010, 10:11:04 PM »
This is probably directed mostly to genetransfer. ;D

Is there any chance you could whip up a silhouette/outline shader?
« Reply #1 on: January 12, 2010, 11:42:15 PM »
Hi Dennis! attached is a silhouette shader (I had one lying around) you can select from 5 predefined colors in the script.
As for an outline shader we will have to wait till we have post-process support as I have one but can't use without post process effects unfortunately. any way hope this is useful. :)

using 3Drad 7.22

system specs:
Windows 7 Home Premium 64-bit
Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz (4 CPUs), ~3.2Ghz
8 gig ram
Geforce GTX 650 1024 MB GDDR5
DirectX 11
« Reply #2 on: January 13, 2010, 10:27:21 PM »
Thanks!
« Reply #3 on: January 16, 2010, 03:45:58 AM »
You can actully do a 2-pass get to the outline without postprocessing.
On second pass do the model slightly larger in the vertex shader color it black and set CullMode = CW.
I can wrap this shader up later tonight and put it up if you need it.
« Last Edit: January 16, 2010, 03:48:14 AM by shadmar »
« Reply #4 on: January 16, 2010, 04:13:11 AM »
hi shadmar, will that method work for meshes that are eregular shaped or boned skinmesh's like andro?
using 3Drad 7.22

system specs:
Windows 7 Home Premium 64-bit
Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz (4 CPUs), ~3.2Ghz
8 gig ram
Geforce GTX 650 1024 MB GDDR5
DirectX 11
« Reply #5 on: January 16, 2010, 06:28:41 AM »
Yes, but that was more work :)
I needed to pass a new vsArray for the second pass, but it did work.

EDIT: And there is a small glitch tho, look at the shoulder.
« Last Edit: January 16, 2010, 06:37:48 AM by shadmar »
« Reply #6 on: January 16, 2010, 07:27:18 AM »
Here it is, based on your base shader-gene :

Code: [Select]

/*HLSLSTART OutLine_Bump_Gloss_Fx_2_0
//---------------------------------------------------------------------
//               Point_Light_Bump_Gloss
//---------------------------------------------------------------------
float Script : STANDARDSGLOBAL <
    string UIWidget = "none";
    string ScriptClass = "object";
    string ScriptOrder = "standard";
    string ScriptOutput = "color";
    string Script = "Technique=NoSkinning;";
> = 0.8;
//---------------------------------------------------------------------
//*********************************************************************
//MATRIX STUFF
//*********************************************************************
#define MATRIX_PALETTE_SIZE_DEFAULT 26

const int MATRIX_PALETTE_SIZE = MATRIX_PALETTE_SIZE_DEFAULT;
float4x3 amPalette[MATRIX_PALETTE_SIZE_DEFAULT];

float4x4 mxWorld : WORLD;
//---------------------------------------------------------------------
//mxWorldIT for use in 3Impact
//float4x4 mxWorldIT : amPalette; //to transform normals (note: we can re-use bone matrices registers as this will only be set for non-skinned meshes)
//---------------------------------------------------------------------
//mxWorldIT for use in fxcomposer
float4x4 mxWorldIT : WORLDINVERSETRANSPOSE;
float4x4 mxViewProj : VIEWPROJECTION;
//*********************************************************************
//LIGHT'S
//*********************************************************************
float4 lightDir : DIRECTION = {0.0f,0.0f,-1.0f,1.0f};
float4 lightColor : DIFFUSE = {1.0f,1.0f,1.0f,1.0f};
float4 lightAmbient : AMBIENT = {0.35f,0.35f,0.35f,1.0f};
//*********************************************************************
//EDITIABLE VALUES
//*********************************************************************
float ScrollSpeed_X <
    string UIName = "Bump Speed X";
    string UIWidget = "slider";
    float UIMin = -0.2;
    float UIMax = 0.2;
    float UIStep = 0.001;
> = 0.0f;

float ScrollSpeed_Y <
    string UIName = "Bump Speed Y";
    string UIWidget = "slider";
    float UIMin = -0.2;
    float UIMax = 0.2;
    float UIStep = 0.001;
> = 0.0f;

static float2 ScrollSpeed = float2(ScrollSpeed_X,ScrollSpeed_Y);

float TileCount <
    string UIWidget = "slider";
    float UIMin = 1.0f;
    float UIMax = 128.0f;
    float UIStep = 0.01f;
    string UIName =  "TileCount";
> = 1.0f;

float bumpScale<
    string UIWidget = "slider";
    float UIMin = 0.0f;
    float UIMax = 10.0f;
    float UIStep = 0.01f;
    string UIName =  "bumpscale";
> = 1.0f;

float SpecIntesity <
    string UIWidget = "slider";
    float UIMin = 0.0f;
    float UIMax = 1.0f;
    float UIStep = 0.01f;
    string UIName =  "specular intesity";
> = 0.75f;

float PhongExp <
    string UIName = "Phong Exponent";
    string UIWidget = "slider";
    float UIMin = 0.0f;
    float UIStep = 8.0f;
    float UIMax = 256.0f;
> = 128.0f;

float discretePallete = 0.1f;
float4 outlineCol;

//*********************************************************************
//USED IN VERTEX SHADER
//*********************************************************************
float3 worldEyePos;
//*********************************************************************
//TEXTURE NAMES
//*********************************************************************
texture diffuseMap : DIFFUSE <
    string ResourceName = "default_color.dds";
    string UIName =  "Color Texture";
    string ResourceType = "2D";
>;
texture NormalMap : NORMAL <
    string ResourceName = "default_bump_normal.dds";
    string UIName =  "Normal-Map Texture";
    string ResourceType = "2D";
>;
//*********************************************************************
//SKINNING STUFF
//*********************************************************************
int boneCount = 2;

struct VS_BONES_INPUT
{
   float4 vPos;
   float3 vBlendWeights;
   float4 vBlendIndices;
   float3 vNor;
   float3 vT;
   float3 vB;
};

struct VS_BONES_OUTPUT
{
   float4 vPos;
   float3 vNor;
   float3 vT;
   float3 vB;
};

VS_BONES_OUTPUT VS_Bones( const VS_BONES_INPUT vInput, int iNumBones )
{
   //This function is called by VS_Skinning(), the main
   //vertex shader function for skinned meshes
   //It applies bone matrices to vertex coordinates, normals and tangents,
   //which also transforms from model-space to world space

   VS_BONES_OUTPUT vOutput = (VS_BONES_OUTPUT) 0;

   float fLastWeight = 1.0;
   float fWeight;
   float afBlendWeights[3] = (float[3])vInput.vBlendWeights;
   int aiIndices[4] = (int[4])D3DCOLORtoUBYTE4(vInput.vBlendIndices);

   for (int iBone=0;(iBone<3) && (iBone<(iNumBones-1));iBone++)
   {
      fWeight = afBlendWeights[iBone];
      fLastWeight -= fWeight;
      vOutput.vPos.xyz += mul(vInput.vPos,amPalette[aiIndices[iBone]])*fWeight;
      vOutput.vNor += mul(vInput.vNor,amPalette[aiIndices[iBone]])*fWeight;
      vOutput.vT += mul(vInput.vT,amPalette[aiIndices[iBone]])*fWeight;
      vOutput.vB += mul(vInput.vB,amPalette[aiIndices[iBone]])*fWeight;
   }

   vOutput.vPos.xyz += mul(vInput.vPos,amPalette[aiIndices[iNumBones-1]])*fLastWeight;
   vOutput.vNor += mul(vInput.vNor,amPalette[aiIndices[iNumBones-1]])*fLastWeight;
   vOutput.vT += mul(vInput.vT,amPalette[aiIndices[iNumBones-1]])*fLastWeight;
   vOutput.vB += mul(vInput.vB,amPalette[aiIndices[iNumBones-1]])*fLastWeight;

   return vOutput;
}
//*********************************************************************
//TEXTURE SAMPLERS
//*********************************************************************
sampler2D ColorSampler = sampler_state {
    Texture = <diffuseMap>;
    MinFilter = Linear;
    MipFilter = Linear;
    MagFilter = Linear;
    AddressU = Wrap;
    AddressV = Wrap;
};
sampler2D NormalMapSampler = sampler_state {
    Texture = <NormalMap>;
    MinFilter = Linear;
    MipFilter = Linear;
    MagFilter = Linear;
    AddressU = Wrap;
    AddressV = Wrap;
};
//*********************************************************************
//INPUT - OUTPUT
//*********************************************************************
struct VS_INPUT
{
   float4 Position : POSITION;
   float3 BlendWeights : BLENDWEIGHT;
   float4 BlendIndices : BLENDINDICES;
   float3 Normal : NORMAL;
   float2 TexCoord : TEXCOORD0;
   float3 T : TEXCOORD1; //in object space
   float3 B : TEXCOORD2; //in object space
};
struct VS_INPUT_NOSKINNING
{
   float4 Position : POSITION; //in object space
   float3 Normal : NORMAL; //in object space
   float2 TexCoord : TEXCOORD0;
   float3 T : TEXCOORD1; //in object space
   float3 B : TEXCOORD2; //in object space
};
struct VS_OUTPUT
{
   float4 Position : POSITION; //in projection space
   float2 TexCoord : TEXCOORD0;
   float3 Normal : TEXCOORD1;   //in tangent space
   float3 Tangent : TEXCOORD2;   //in tangent space
   float3 Binormal : TEXCOORD3;   //in tangent space
   float3 ViewVec : TEXCOORD4;
   float4 LightVec : TEXCOORD5;
};
//*********************************************************************
//VERTEX SHADER - FUNCTIONS
//*********************************************************************
//------------------------------------------------------------------
float3x3 SkinnedObjTanSpace(float3 tangent,float3 binormal,float3 normal)
{
   float3x3 OTS;
   OTS[0] =  bumpScale * normalize(tangent);
   OTS[1] =  bumpScale * normalize(binormal);
   OTS[2] = normalize(normal);
   return OTS;
}
//------------------------------------------------------------------
float3x3 NonSkinnedObjTanSpace(float3 tangent,float3 binormal,float3 normal)

   float3x3 OTS;
   OTS[0] = bumpScale * mul(tangent,mxWorldIT);
   OTS[1] = bumpScale * mul(binormal,mxWorldIT);
   OTS[2] = mul(normal,mxWorldIT);
   return OTS;
}
//*********************************************************************
//SKINNED - VERTEX SHADER
//*********************************************************************
VS_OUTPUT VS_Skinning(VS_INPUT IN, uniform int iNumBones, uniform float size)
{
    VS_OUTPUT OUT;
   
    VS_BONES_INPUT vsi = { IN.Position, IN.BlendWeights, IN.BlendIndices, IN.Normal, IN.T, -IN.B };
    VS_BONES_OUTPUT vso = VS_Bones( vsi, iNumBones );
    //-----------------------------------------------------------------
    //texture coords
    OUT.TexCoord = TileCount * IN.TexCoord.xy + (1.0f * ScrollSpeed);
    //-----------------------------------------------------------------
    //position
    OUT.Position = mul(float4(vso.vPos.xyz,1.0f),mxViewProj)+(mul(size, mul(IN.Normal, mxViewProj)));
    //-----------------------------------------------------------------
    // Compute matrix which transforms to tangent space
    float3x3 objToTangentSpace = SkinnedObjTanSpace(vso.vT,vso.vB,vso.vNor);
    OUT.Tangent = objToTangentSpace[0];
    OUT.Binormal = objToTangentSpace[1];
    OUT.Normal = objToTangentSpace[2];
    //-----------------------------------------------------------------
    // compute view vector
    OUT.ViewVec = normalize(worldEyePos - mul(IN.Position,mxWorld));
    //-----------------------------------------------------------------
    //point light vector
    OUT.LightVec = -lightDir;
   
    return OUT;
}
//*********************************************************************
//NON - SKINNED - VERTEX SHADER
//*********************************************************************
VS_OUTPUT VS_NoSkinning(VS_INPUT_NOSKINNING IN, uniform float size)
{
    VS_OUTPUT OUT;
    //-----------------------------------------------------------------
    //texture coords
    OUT.TexCoord = TileCount * IN.TexCoord.xy + (1.0f * ScrollSpeed);
    //-----------------------------------------------------------------
    //position
    OUT.Position = mul(IN.Position,mxViewProj)+(mul(size, mul(IN.Normal, mxViewProj)));
    //-----------------------------------------------------------------
   // Compute matrix which transforms to tangent space
    float3x3 objToTangentSpace = NonSkinnedObjTanSpace(IN.T,-IN.B,IN.Normal);
    OUT.Tangent = objToTangentSpace[0];
    OUT.Binormal = objToTangentSpace[1];
    OUT.Normal = objToTangentSpace[2];
    //-----------------------------------------------------------------
    // compute view vector
    OUT.ViewVec = normalize(worldEyePos - mul(IN.Position,mxWorld));
    //-----------------------------------------------------------------
    //point light vector
    OUT.LightVec = -lightDir;
   
    return OUT;
}
//*********************************************************************
//PIXEL SHADER - FUNCTIONS
//*********************************************************************
float3 lightmodelA(float3 Ln,float3 Hn,float3 Nb)
{
    float att = saturate(dot(Ln,Nb));
    float diff = saturate(dot(Ln,Nb));
    float spec = saturate(dot(normalize(Hn),Nb));
    spec = pow(spec,PhongExp);
    return float3(att,diff,spec);
}
//*********************************************************************
//PIXEL SHADER
//*********************************************************************
float4 PS_PixScene(VS_OUTPUT IN, uniform bool shadeoutline) : COLOR
{
    //-----------------------------------------------------------------
    //fetch base color
    float4 color = tex2D(ColorSampler,IN.TexCoord);
    //-----------------------------------------------------------------
    //fetch bump normal and expand
    float3 bumpNormal = 2.0f * tex2D(NormalMapSampler, IN.TexCoord.xy) - 1.0f;
    float3 Tn = IN.Tangent;
    float3 Bn = IN.Binormal;
    float3 Nn = IN.Normal;
    float3 Nb = Nn + (bumpNormal.x * Tn + bumpNormal.y * Bn);
    Nb = normalize(Nb);
    //-----------------------------------------------------------------
    //view, light and halfangle vector
    float3 Vn = normalize(IN.ViewVec);
    float3 Ln = normalize(IN.LightVec.xyz);
    float3 Hn = normalize(Ln+Vn);
    //-----------------------------------------------------------------
    //lighting
    float3 Lighting = lightmodelA(Ln,Hn,Nb);   
    //-----------------------------------------------------------------
    //compute final color
    float3 finalcolor = lightAmbient*color.xyz + Lighting.x*(color*lightColor.xyz*Lighting.y+SpecIntesity*Lighting.z);
    //float3 finalcolor = color*lightColor;

    if (shadeoutline) //Outline second pass
    {
         return float4(0,0,0,1);  //RGBA for the outline
    }
    else
    {
         return float4(finalcolor,color.w);
    }
}
//*********************************************************************
//TECHNIQUES
//*********************************************************************
VertexShader vsArray[4] = { compile vs_2_0 VS_Skinning(1,0),
                            compile vs_2_0 VS_Skinning(2,0),
                            compile vs_2_0 VS_Skinning(3,0),
                            compile vs_2_0 VS_Skinning(4,0) };

VertexShader vsArrayOutline[4] = {  compile vs_2_0 VS_Skinning(1,0.02),
                                    compile vs_2_0 VS_Skinning(2,0.02),
                                    compile vs_2_0 VS_Skinning(3,0.02),
                                    compile vs_2_0 VS_Skinning(4,0.02) };

technique Skinning
{
   pass P0
   {
      VertexShader = (vsArray[boneCount]);
      PixelShader = compile ps_2_0 PS_PixScene(false);
   }
   pass P1
   {
      VertexShader = (vsArrayOutline[boneCount]);
      PixelShader = compile ps_2_0 PS_PixScene(true);
      CullMode = CW;
   }
}
technique NoSkinning<
string Script = "Pass=p0;";
> {
pass p0  <
string Script = "Draw=geometry;";
> {
   VertexShader = compile vs_2_0 VS_NoSkinning(0);
   PixelShader  = compile ps_2_0 PS_PixScene(false);
    }
   pass p1  <
string Script = "Draw=geometry;";
> {
   VertexShader = compile vs_2_0 VS_NoSkinning(.02);
   PixelShader  = compile ps_2_0 PS_PixScene(true);
      CullMode = CW;
    }
}
HLSLEND*/

//******************************************************************
//MAIN
//******************************************************************



void Main()
{
   if (iDeinitializing())
   { 
   }
   if (iInitializing())
   { 
      int i=0;
      while ( iObjectHandle(i) != -1)
      {
         iShaderSet(iObjectHandle(i),"OutLine_Bump_Gloss_Fx_2_0");
         i++;
      }
   } 
}





 

EDIT: Add this to the pixelshader get the toon effect aswell

finalcolor.rgb -= (finalcolor.rgb % 0.08f );


Have fun :)
« Last Edit: January 16, 2010, 02:27:34 PM by shadmar »
« Reply #7 on: January 16, 2010, 11:40:06 PM »
That's pretty darn close to what I was looking for shadmar, thanks guys!
« Reply #8 on: January 17, 2010, 12:11:30 AM »
yeah good job shadmar!
using 3Drad 7.22

system specs:
Windows 7 Home Premium 64-bit
Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz (4 CPUs), ~3.2Ghz
8 gig ram
Geforce GTX 650 1024 MB GDDR5
DirectX 11
« Reply #9 on: April 05, 2010, 09:50:34 PM »
Sorry to bring up an old thread people but can anyone tell how you could make the black outline thicker in the shader? For incredible large objects, it's almost invisible unless you're close.
« Reply #10 on: April 06, 2010, 01:26:02 AM »
Increase the resize input for the second pass (in red, higher = thicker outline)

For non boned :

   pass p1  <
      string Script = "Draw=geometry;";
   > {   
      VertexShader = compile vs_2_0 VS_NoSkinning(.02);
      PixelShader  = compile ps_2_0 PS_PixScene(true);
      CullMode = CW;
    }

For boned

VertexShader vsArrayOutline[4] = {  compile vs_2_0 VS_Skinning(1,0.02),
                                    compile vs_2_0 VS_Skinning(2,0.02),
                                    compile vs_2_0 VS_Skinning(3,0.02),
                                    compile vs_2_0 VS_Skinning(4,0.02) };
« Reply #11 on: April 06, 2010, 01:53:03 AM »
thanks very much shadmar! I really must learn hlsl when I've got time
Pages: [1]