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 question/request - Color color with mask  (Read 1024 times)

Mic

« on: March 12, 2010, 09:40:17 AM »
I have an object that I would like to change the color of while in game. I would like the allow the user to pick a primary color and secondary color. It would have a predefined texture mask that would identify the color areas. On my end, the user could use a key input to move the settings of both colors.

Also, can this effect be achieved with shader 2.0? Thanks!!!
« Reply #1 on: March 12, 2010, 01:01:27 PM »
You could try this one (Genes base shader slightly modded), it reads the black and white off your texture and replaces it.
You need to set RGB in script like this (look at bottom of the shader) :

   iShaderFloat3Set(OBJ_0,"whitemask",1,1,0);        // color to replace white mask
   iShaderFloat3Set(OBJ_0,"blackmask",1,0,1);        // color to replace black mask

PS! Also if you need it normalmapped you need to set the path

Code: [Select]


/*HLSLSTART Masked_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;


float3 blackmask;
float3 whitemask;

//*********************************************************************
//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);

    if (color.r+color.g+color.b+color.a == 1) {
         color.rgb = blackmask;
    }
    else
    {
         color.rgb = whitemask;
    }

    //-----------------------------------------------------------------
    //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);
    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();
   }
}
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();
    }
}
HLSLEND*/

//******************************************************************
//MAIN
//******************************************************************
   
int myTexture0;

void Main()
{
   if (iDeinitializing())
   { 
       iShaderTextureDestroy(myTexture0);
   }
   if (iInitializing())
   { 
      iShaderSet(OBJ_0,"Masked_Bump_Gloss_Fx_2_0");
      myTexture0 = iShaderTextureCreate("\\path\to\normalmap");  //point this to your normalmap
   } 
   iShaderTextureSet(OBJ_0,"NormalMap",myTexture0);
   iShaderFloat3Set(OBJ_0,"whitemask",1,1,0);        // color to replace white mask
   iShaderFloat3Set(OBJ_0,"blackmask",1,0,1);        // color to replace black mask
}

Mic

« Reply #2 on: March 12, 2010, 01:16:19 PM »
Thank you "shader'mar" :)

And dang! That sure seems like a lot of text for such a simple action.
Pages: [1]