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] 2

Author Topic: Simple TreeShader (for 6.41+)  (Read 4319 times)

« on: February 20, 2010, 02:30:45 PM »
TreeShader for 3dRad 6.41+

This is just a simple TreeShader.
It solves these common issues :

 - backsides being culled
 - transparency in textures
 - no Z buffer issues.


Example :


3dRad default shader:

BAcksides are being culled and transparent textures doesn't look too good.



TreeShader:

You can see no backsides being culled, and no transparency issues.





How to USe/Install


1. Copy the shader below and paste to a script in your project.
2. Add your tree skinmesh, Check Use Custom Shader
3. Link to script.


You can tweak these in the technique section :
ALPHAREF = 0x000000AF;   //Use values from 00-FF to tweak tranparent texture filtering

Code: [Select]



/*HLSLSTART TreeShader
//---------------------------------------------------------------------
//               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";
> = 0.0f;

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

float PhongExp <
    string UIName = "Phong Exponent";
    string UIWidget = "slider";
    float UIMin = 0.0f;
    float UIStep = 8.0f;
    float UIMax = 256.0f;
> = 128.0f;
//*********************************************************************
//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)
{
    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);
    //-----------------------------------------------------------------
    // 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)
{
    VS_OUTPUT OUT;
    //-----------------------------------------------------------------
    //texture coords
    OUT.TexCoord = TileCount * IN.TexCoord.xy + (1.0f * ScrollSpeed);
    //-----------------------------------------------------------------
    //position
    OUT.Position = mul(IN.Position,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) : 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
    float shadow = saturate(0*Lighting);
    float3 finalcolor = (lightAmbient+shadow)*color.xyz +
    Lighting.x*(color*lightColor.xyz*Lighting.y+SpecIntesity*Lighting.z);
    return float4(finalcolor.rgb,color.w);
   
}
//*********************************************************************
//TECHNIQUES
//*********************************************************************
VertexShader vsArray[4] = { compile vs_2_0 VS_Skinning(1),
                            compile vs_2_0 VS_Skinning(2),
                            compile vs_2_0 VS_Skinning(3),
                            compile vs_2_0 VS_Skinning(4) };

technique Skinning
{
   pass P0
   {
      VertexShader = (vsArray[boneCount]);
      PixelShader = compile ps_2_0 PS_PixScene();
      ZWriteEnable = true;
      AlphaBlendEnable = true;
      ALPHATESTENABLE = true;
      ALPHAFUNC = greaterequal;
      ALPHAREF = 0x000000AF;
      CULLMODE=None;
   }
}
technique NoSkinning<
string Script = "Pass=p0;";
> {

pass p0  <
string Script = "Draw=geometry;";
> {
   VertexShader = compile vs_2_0 VS_NoSkinning();
   PixelShader  = compile ps_2_0 PS_PixScene();
      ZWriteEnable = true;
      AlphaBlendEnable = true;
      ALPHATESTENABLE = true;
      ALPHAFUNC = greaterequal;
      ALPHAREF = 0x000000AF;
      CULLMODE=None;
    }
}
HLSLEND*/


//******************************************************************
//MAIN
//******************************************************************
   
int myTexture0,myTexture1;

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





 

« Last Edit: February 20, 2010, 02:35:56 PM by shadmar »
« Reply #1 on: February 20, 2010, 02:51:41 PM »
The difference is from here to the moon! :) Great stuff  :o
Roll out!
http://www.youtube.com/watch?v=VD8MvMaPNO4

Do you have kids between the ages of 3 and 9?

http://www.amazon.com/dp/B007K1EFC6

leon

« Reply #2 on: February 20, 2010, 03:14:30 PM »
nice
works good
was playing with the imposter the other day and noticed that i could not get trees right so i gave up.
But all's good now
make some nice forest now
cheers  ;D
« Reply #3 on: February 20, 2010, 04:37:19 PM »
Brilliant solution!
« Reply #4 on: February 22, 2010, 02:17:57 AM »
Looks very nice!
FPS game creator for 3drad and >2000 games GamesAtNight
« Reply #5 on: February 22, 2010, 03:08:26 AM »
very cool Shad!
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 #6 on: February 26, 2010, 06:02:04 AM »
Very nice! is that the exact same model? just with and without the shader? Very impressive!
« Reply #7 on: February 26, 2010, 06:38:37 AM »
Yes same tree, 4 polys, two planes crossed as an X with a transparent texture
« Reply #8 on: February 26, 2010, 07:32:56 AM »
thank you very much Shadmar, I really thought I would never see a decent tree solution in 3dRad.
I believe in miracles now  :D
Crashing Boxes - winner of the 3d games category at the 5th Uruguayan video game contest
get a copy for your iPad/iPhone!
« Reply #9 on: February 26, 2010, 08:34:12 AM »
Far back in my head I remember some issue about this or something similar ;)
« Reply #10 on: June 20, 2010, 09:14:59 PM »
I Am trying the tree shader in conjunction to the imposter script, but I keep getting weird effects. Some (not all) of my impostor trees look as if the have the emmisive shader applied to them. The original tree skin mesh always looks right. Just some of the impostor trees have a really bright color to them similar to the emmisive shader.  I am using DDS textures with alpha. Any Ideas?
« Reply #11 on: June 21, 2010, 12:56:52 AM »
Might be  bug, post some screenshots.
FPS game creator for 3drad and >2000 games GamesAtNight
« Reply #12 on: June 21, 2010, 09:01:56 AM »
The first pic shows the impostor plotter along side a tree that was already plotted and loaded back into the map. The second pic shows the impostor plotter along with one of the same trees that was plotted before.
« Reply #13 on: June 22, 2010, 12:47:43 PM »
Could anyone confirm if this might be a bug? Or if there is something in the script I could modify? I know absolutely nothing about shaders, but it appears to me as if something in the shader script is lighting some of the faces of the skinmesh.
« Reply #14 on: June 22, 2010, 02:17:28 PM »
The shader should inherit light direction and color from the sunlight object.
I can't seem to reproduce. Could you post the entire project, or a test project which gives this bug for me to examine?
Pages: [1] 2