Game Development Community

help!! porting shader, but no "main" in shader, where to put it???

by deepscratch · in Torque 3D Professional · 08/29/2010 (11:55 am) · 3 replies

hi all,
I've been working on getting this
shader into T3D (its that blood/gravity shader), I'm sitting with a problem, there is no "main" entry point, and I cant work out where to put it, and how. help?

I've given the original code and my port of it, as it is now.

this is the original shader code:
//HLSL BloodShader FX File
//This Sample illustrates per pixel animation by defining gravity at every point across a texture

//Define the Min height the Blood can have and still move
#define MinBloodHeight 0.4f

//Blood Color initialized to red 
float3 BloodColor = float3(.928, .156, .156);

//Point size 1/512 for 512x512 RT
#define pSize 0.001953125

//Define World Gravity as pointing in the negative Z direction
#define GRAVITY float3(0.0f, 0.0f, -1.0f)

float4x4 World : World;  
float4x4 WorldViewProjection : WorldViewProjection;

//NormalMap: Texture that represents the Normal Map for the mesh
texture NormalMap;
sampler2D NormalMapSampler = sampler_state 
{
    Texture = <NormalMap>;
    AddressU = CLAMP;
    AddressV = CLAMP;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
};

//DiffuseMap: Texture that represents the Texture Map for the mesh
texture DiffuseMap;
sampler2D DiffuseMapSampler = sampler_state 
{
    Texture = <DiffuseMap>;
    AddressU = CLAMP;
    AddressV = CLAMP;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
};

//GravityMap: A texture representing gravity at each point in Texture Space
texture GravityMap;
sampler2D GravityMapSampler = sampler_state 
{
    Texture = <GravityMap>;
    AddressU = WRAP;
    AddressV = WRAP;
    MinFilter = POINT;
    MagFilter = POINT;
    MipFilter = POINT;
};
//FinalBlend: Also samples the GravityMap but does so with a linear filter(for the final display)
sampler2D FinalBlend = sampler_state 
{
    Texture = <GravityMap>;
    AddressU = WRAP;
    AddressV = WRAP;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
};
texture RawMap;
sampler2D FinalBlend = sampler_state 
{
    Texture = <RawMap>;
    AddressU = WRAP;
    AddressV = WRAP;
    MinFilter = POINT;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
};


//--------------------Shaders-----------------------------------
struct VS_GravityIn 
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL; 
    float2 Tex : TEXCOORD;
    float3 Tan : TANGENT; 
    float3 Bin : BINORMAL;
};

struct VS_GravityOut
{
    float4 Pos : POSITION;
    float2 Tex: TEXCOORD0;
    float2 TexAbove : TEXCOORD1;
    float2 TexBelow : TEXCOORD2;
    float2 TexLeft : TEXCOORD3;
    float2 TexRight : TEXCOORD4;
    float2 Grav : TEXCOORD5;
};

VS_GravityOut VS_GravityMap(VS_GravityIn In)
{
    VS_GravityOut Out = (VS_GravityOut)0;
    Out.Pos = float4(2*(In.Tex.x-.5) - pSize, -2*(In.Tex.y -.5) + pSize, 0, 1);

    //Center Texel
    Out.Tex.x = In.Tex.x;
    Out.Tex.y = In.Tex.y;
    
    //Texel Above
    Out.TexAbove.x = In.Tex.x;
    Out.TexAbove.y = In.Tex.y - pSize;
    
    //Texel Below
    Out.TexBelow.x = In.Tex.x;
    Out.TexBelow.y = In.Tex.y + pSize;
    

    //Texel to the Left
    Out.TexLeft.x = In.Tex.x - pSize;
    Out.TexLeft.y = In.Tex.y;
    
    //Texel to the Right
    Out.TexRight.x = In.Tex.x + pSize;
    Out.TexRight.y = In.Tex.y;

    float3 Gravity = mul(GRAVITY, transpose(World));
    //Gravity is now in object space
    float3x3 ObjectToTan ={In.Tan, In.Bin, In.Norm};
    Gravity = mul(Gravity, ObjectToTan);
    Gravity = normalize(Gravity);
    //Gravity is now in tangent space
    Out.Grav.xy = Gravity.xy;
    
    return Out;
}

float4 PS_GravityMap (VS_GravityOut In) : COLOR
{
    float4 Out = (float4)0;
 
    float Blood = 0;
    float4 Grab = (float4)0;
    float MyGrav;
    //What's up with my blood
    Grab = tex2D(GravityMapSampler, In.Tex);
    MyGrav = abs(2*(Grab.x -.5)) + abs(2*(Grab.y - .5));
    Blood = Grab.b - MyGrav*Grab.b;
   
    //Above
    Grab = tex2D(GravityMapSampler, In.TexAbove);
    MyGrav = -2*(Grab.y - .5);
    if(MyGrav > 0) Blood += MyGrav*Grab.b;
  
    //Below
    Grab = tex2D(GravityMapSampler, In.TexBelow);
    MyGrav = 2*(Grab.y - .5);
    if(MyGrav> 0)Blood += MyGrav*Grab.b;

    //Left
    Grab = tex2D(GravityMapSampler, In.TexLeft);
    MyGrav = -2*(Grab.x - .5);
    if(MyGrav> 0) Blood += MyGrav*Grab.b;
    
    //Right
    Grab = tex2D(GravityMapSampler, In.TexRight);
    MyGrav = 2*(Grab.x - .5);
    if(MyGrav> 0) Blood += MyGrav*Grab.b;

    float2 BloodDir = (float2)0;

    if(Blood > MinBloodHeight)
    {
    float3 Normal = tex2D(NormalMapSampler, In.Tex).rgb;
    Normal = 2*(Normal - .5);
    BloodDir = Normal.xy+In.Grav.xy;
    BloodDir = clamp(BloodDir, -1, 1);
    BloodDir = pow(BloodDir, 3);
    }
    Out.xy = (.5*BloodDir) +.5;
    Out.b = Blood;
    return Out;
}


struct VS_FinalOut
{
    float4 Pos : POSITION;
    float2 Tex : TEXCOORD;
    float3 Light : TEXCOORD2;
    float2 TexAbove : TEXCOORD3;
    float2 TexBelow : TEXCOORD4;
    float2 TexLeft : TEXCOORD5;
    float2 TexRight : TEXCOORD6;
    float3 View : TEXCOORD7;
};

VS_FinalOut VS_FinalBlend(VS_GravityIn In)
{
    VS_FinalOut Out = (VS_FinalOut)0;
    Out.Tex = In.Tex;
    Out.Pos = mul(float4(In.Pos,1), WorldViewProjection);

    //Texel Above
    Out.TexAbove.x = In.Tex.x;
    Out.TexAbove.y = In.Tex.y - pSize;
    
    //Texel Below
    Out.TexBelow.x = In.Tex.x;
    Out.TexBelow.y = In.Tex.y + pSize;
    

    //Texel to the Left
    Out.TexLeft.x = In.Tex.x - pSize;
    Out.TexLeft.y = In.Tex.y;
    
    //Texel to the Right
    Out.TexRight.x = In.Tex.x + pSize;
    Out.TexRight.y = In.Tex.y;
    
    float3x3 ObjectToTan ={In.Tan, In.Bin, In.Norm};
    float3 Light = mul(float3(0.0f, 1.0f, 0.0f), transpose(World));
    //Light vector is now in object space
    Out.Light = mul(Light, ObjectToTan);
    //Light vector is now in tangent space
    
    //Move view vector into tangent space
    float3 View = float3(0,1,0);
    View = mul(View, transpose(World));
    Out.View = mul(View, ObjectToTan);
    
    return Out;
}

float4 PS_FinalBlend(VS_FinalOut In) : COLOR
{
    float4 Color = (float4)0;
    float3 Light = -In.Light;
    float3 View = -In.View;
    Light = normalize(Light);
    
    
    //Get the height of the Blood in this texel
    float Blood = tex2D(FinalBlend, In.Tex).b;
    //Raising Blood to a power of .33 to increase it's intensity
    Blood = pow(Blood,.33);
    //Use this value to determine amount of Blood to be placed at this texel
    float3 BloodOut = Blood*float3(BloodColor);

    //Compute deltas to determine blood normal
    float dx = tex2D(FinalBlend, In.TexRight).b - tex2D(FinalBlend, In.TexLeft).b;
    float dy = tex2D(FinalBlend, In.TexBelow).b - tex2D(FinalBlend, In.TexAbove).b;

    //Get the color for this texel from texture map
    Color = tex2D(DiffuseMapSampler, In.Tex);
    //Add Blood Color
    Color.rgb = Color.rgb*(1-Blood) + BloodOut;

    //Dot3 Specular Lighting calculation
    float3 Normal = tex2D(NormalMapSampler, In.Tex);
    Normal = 2*(Normal-.5);

    //Add the blood's contribution to this normal
    Normal = normalize(Normal + float3(dx, dy, 0));
    //Compute final color
    Color.rgb = Color*.3 + Color*max(0, dot(Light, Normal))*.7 + pow(dot(reflect(Light, Normal), View),30)*.3;
    return Color;
}


technique ComputeGravity
{
    pass Gravity
    {
        VertexShader = compile vs_1_1 VS_GravityMap();
        PixelShader = compile ps_2_0 PS_GravityMap();
    }
}


technique FinalBlend
{
    pass Blend
    {
        VertexShader = compile vs_1_1 VS_FinalBlend();
        PixelShader = compile ps_2_0 PS_FinalBlend();
    }
}


and these are my P and V shaders:
P shader:
//-----------------------------------------------------------------------------
// Torque 3D
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

//This Sample illustrates per pixel animation by defining gravity at every point across a texture

#include "../postFx.hlsl"
#define IN_HLSL
#include "../../shdrConsts.h"
 #include "shadergen:/autogenConditioners.h"
 
uniform float4x4 world           : register(C8);  
uniform float4x4 modelview       : register(VC_WORLD_PROJ);

uniform float3    eyePosWorld;
uniform float4    rtParams0;
uniform float     accumTime;

//Define the Min height the Blood can have and still move
#define MinBloodHeight 0.4f

//Blood Color initialized to red 
float3 BloodColor = float3(.928, .156, .156);

//Point size 1/512 for 512x512 RT
#define pSize 0.001953125

//Define World Gravity as pointing in the negative Z direction
#define GRAVITY float3(0.0f, 0.0f, -1.0f)

struct VS_GravityOut
{
    float4 Pos : POSITION;
    float2 Tex: TEXCOORD0;
    float2 TexAbove : TEXCOORD1;
    float2 TexBelow : TEXCOORD2;
    float2 TexLeft : TEXCOORD3;
    float2 TexRight : TEXCOORD4;
    float2 Grav : TEXCOORD5;
};

struct VS_FinalOut
{
    float4 Pos : POSITION;
    float2 Tex : TEXCOORD;
    float3 Light : TEXCOORD2;
    float2 TexAbove : TEXCOORD3;
    float2 TexBelow : TEXCOORD4;
    float2 TexLeft : TEXCOORD5;
    float2 TexRight : TEXCOORD6;
    float3 View : TEXCOORD7;
};

float4 VS_GravityMap (VS_GravityOut IN,
             uniform sampler2D prepassTex          :register(S0),
             uniform sampler2D NormalMapSampler    :register(S1),
             uniform sampler2D DiffuseMapSampler   :register(S2),
             uniform sampler2D GravityMapSampler   :register(S3),
             uniform sampler2D FinalBlend          :register(S4),
             uniform sampler2D RawMapSampler       :register(S5),
             uniform float2 targetSize             :register(C0) ) : COLOR
{
    float4 Out = (float4)0;
 
    float Blood = 0;
    float4 Grab = (float4)0;
    float MyGrav;
    //What's up with my blood
    Grab = tex2D(GravityMapSampler, IN.Tex);
    MyGrav = abs(2*(Grab.x -.5)) + abs(2*(Grab.y - .5));
    Blood = Grab.b - MyGrav*Grab.b;
   
    //Above
    Grab = tex2D(GravityMapSampler, IN.TexAbove);
    MyGrav = -2*(Grab.y - .5);
    if(MyGrav > 0) Blood += MyGrav*Grab.b;
  
    //Below
    Grab = tex2D(GravityMapSampler, IN.TexBelow);
    MyGrav = 2*(Grab.y - .5);
    if(MyGrav> 0)Blood += MyGrav*Grab.b;

    //Left
    Grab = tex2D(GravityMapSampler, IN.TexLeft);
    MyGrav = -2*(Grab.x - .5);
    if(MyGrav> 0) Blood += MyGrav*Grab.b;
    
    //Right
    Grab = tex2D(GravityMapSampler, IN.TexRight);
    MyGrav = 2*(Grab.x - .5);
    if(MyGrav> 0) Blood += MyGrav*Grab.b;

    float2 BloodDir = (float2)0;

    if(Blood > MinBloodHeight)
    {
    float3 Normal = tex2D(NormalMapSampler, IN.Tex).rgb;
    Normal = 2*(Normal - .5);
    BloodDir = Normal.xy+IN.Grav.xy;
    BloodDir = clamp(BloodDir, -1, 1);
    BloodDir = pow(BloodDir, 3);
    }
    Out.xy = (.5*BloodDir) +.5;
    Out.b = Blood;
    return Out;
}

float4 PS_FinalBlend (VS_FinalOut IN,
             uniform sampler2D prepassTex          :register(S0),
             uniform sampler2D NormalMapSampler    :register(S1),
             uniform sampler2D DiffuseMapSampler   :register(S2),
             uniform sampler2D GravityMapSampler   :register(S3),
             uniform sampler2D FinalBlend          :register(S4),
             uniform sampler2D RawMapSampler       :register(S5),
             uniform float2 targetSize             :register(C0) ) : COLOR
{
    float4 Color = (float4)0;
    float3 Light = -IN.Light;
    float3 View = -IN.View;
    Light = normalize(Light);
    
    
    //Get the height of the Blood in this texel
    float Blood = tex2D(FinalBlend, IN.Tex).b;
    //Raising Blood to a power of .33 to increase it's intensity
    Blood = pow(Blood,.33);
    //Use this value to determine amount of Blood to be placed at this texel
    float3 BloodOut = Blood*float3(BloodColor);

    //Compute deltas to determine blood normal
    float dx = tex2D(FinalBlend, IN.TexRight).b - tex2D(FinalBlend, IN.TexLeft).b;
    float dy = tex2D(FinalBlend, IN.TexBelow).b - tex2D(FinalBlend, IN.TexAbove).b;

    //Get the color for this texel from texture map
    Color = tex2D(DiffuseMapSampler, IN.Tex);
    //Add Blood Color
    Color.rgb = Color.rgb*(1-Blood) + BloodOut;

    //Dot3 Specular Lighting calculation
    float3 Normal = tex2D(NormalMapSampler, IN.Tex);
    Normal = 2*(Normal-.5);

    //Add the blood's contribution to this normal
    Normal = normalize(Normal + float3(dx, dy, 0));
    //Compute final color
    Color.rgb = Color*.3 + Color*max(0, dot(Light, Normal))*.7 + pow(dot(reflect(Light, Normal), View),30)*.3;
    return Color;
}

and the V shader:
//-----------------------------------------------------------------------------
// Torque 3D
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

#define IN_HLSL
#include "../../shdrConsts.h"

float4x4 World : World;  
float4x4 WorldViewProjection : WorldViewProjection;

struct VS_GravityIn 
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL; 
    float2 Tex : TEXCOORD;
    float3 Tan : TANGENT; 
    float3 Bin : BINORMAL;
};

VS_GravityOut VS_GravityMap(VS_GravityIn In)
{
    VS_GravityOut Out = (VS_GravityOut)0;
    Out.Pos = float4(2*(IN.Tex.x-.5) - pSize, -2*(IN.Tex.y -.5) + pSize, 0, 1);

    //Center Texel
    Out.Tex.x = IN.Tex.x;
    Out.Tex.y = IN.Tex.y;
    
    //Texel Above
    Out.TexAbove.x = IN.Tex.x;
    Out.TexAbove.y = IN.Tex.y - pSize;
    
    //Texel Below
    Out.TexBelow.x = IN.Tex.x;
    Out.TexBelow.y = IN.Tex.y + pSize;
    

    //Texel to the Left
    Out.TexLeft.x = IN.Tex.x - pSize;
    Out.TexLeft.y = IN.Tex.y;
    
    //Texel to the Right
    Out.TexRight.x = IN.Tex.x + pSize;
    Out.TexRight.y = IN.Tex.y;

    float3 Gravity = mul(GRAVITY, transpose(World));
    //Gravity is now in object space
    float3x3 ObjectToTan ={IN.Tan, IN.Bin, IN.Norm};
    Gravity = mul(Gravity, ObjectToTan);
    Gravity = normalize(Gravity);
    //Gravity is now in tangent space
    Out.Grav.xy = Gravity.xy;
    
    return Out;
}

VS_FinalOut VS_FinalBlend(VS_GravityIn IN)
{
    VS_FinalOut Out = (VS_FinalOut)0;
    Out.Tex = IN.Tex;
    Out.Pos = mul(float4(IN.Pos,1), modelview);

    //Texel Above
    Out.TexAbove.x = IN.Tex.x;
    Out.TexAbove.y = IN.Tex.y - pSize;
    
    //Texel Below
    Out.TexBelow.x = IN.Tex.x;
    Out.TexBelow.y = IN.Tex.y + pSize;
    

    //Texel to the Left
    Out.TexLeft.x = IN.Tex.x - pSize;
    Out.TexLeft.y = IN.Tex.y;
    
    //Texel to the Right
    Out.TexRight.x = IN.Tex.x + pSize;
    Out.TexRight.y = IN.Tex.y;
    
    float3x3 ObjectToTan ={IN.Tan, IN.Bin, IN.Norm};
    float3 Light = mul(float3(0.0f, 1.0f, 0.0f), transpose(World));
    //Light vector is now in object space
    Out.Light = mul(Light, ObjectToTan);
    //Light vector is now in tangent space
    
    //Move view vector into tangent space
    float3 View = float3(0,1,0);
    View = mul(View, transpose(World));
    Out.View = mul(View, ObjectToTan);
    
    return Out;
}

and this is my script file:
//-----------------------------------------------------------------------------
// Torque 3D
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

singleton ShaderData( PFX_GravityShader )
{   
   DXPixelShaderFile 	= "shaders/common/postFx/gravity/gravityV.hlsl";
   DXPixelShaderFile 	= "shaders/common/postFx/gravity/gravityP.hlsl";
         
   //OGLVertexShaderFile  = "shaders/common/postFx/gl//postFxV.glsl";
   //OGLPixelShaderFile   = "shaders/common/postFx/gl/passthruP.glsl";
      
   samplerNames[0] = "$prepassTex";
   samplerNames[1] = "$NormalMapSampler";
   samplerNames[2] = "$DiffuseMapSampler";
   samplerNames[3] = "$GravityMapSampler";
   samplerNames[4] = "$FinalBlend";
   samplerNames[5] = "$RawMapSampler";
   
   pixVersion = 3.0;
};

new GFXSamplerStateData(GravitySampler)
{
   textureColorOp = GFXTOPModulate;
   addressModeU = GFXAddressWrap;
   addressModeV = GFXAddressWrap;
   addressModeW = GFXAddressWrap;
   magFilter = GFXTextureFilterLinear;
   minFilter = GFXTextureFilterAnisotropic;
   mipFilter = GFXTextureFilterLinear;
   maxAnisotropy = 4;
};

singleton GFXStateBlockData( PFX_GravityStateBlock : PFX_DefaultStateBlock )
{
   blendDefined = true;
   blendEnable = true; 
   blendSrc = GFXBlendOne;
   blendDest = GFXBlendOne;
   
   samplersDefined = true;
   samplerStates[0] = SamplerClampLinear;
   samplerStates[1] = SamplerClampLinear;
   samplerStates[2] = SamplerClampLinear;
   samplerStates[3] = SamplerWrapLinear;
   samplerStates[4] = SamplerWrapLinear;
   samplerStates[5] = SamplerWrapLinear;
};

singleton CustomMaterial( Gravity )
{   
   sampler["prepassTex"] = "#prepass";
   sampler["reflectMap"] = "$reflectbuff";
   sampler["refractBuff"] = "$backbuff";
   
   shader = PFX_GravityShader;
   stateBlock = PFX_GravityStateBlock;
   version = 3.0;
   
   useAnisotropic[0] = true;
};

singleton PostEffect( GravityPFX )
{
   requirements = "None";
   isEnabled = true;
   renderTime = "PFXBeforeBin";
   renderBin = "ObjTranslucentBin";      
   //renderPriority = 0.1;
      
   shader = PFX_GravityShader;
   stateBlock = PFX_GravityStateBlock;
   texture[0] = "#prepass";
   texture[1] = "textures/GravityNormalMap";
   texture[2] = "textures/GravityDiffuseMap";
   texture[3] = "textures/GravityPhysicalMap";
   texture[4] = "$backBuffer";
   texture[5] = "textures/GravityRawMap";
   target = "$backBuffer";
   
};

$GravityPFX::refTime = getSimTime();

function GravityPFX::setShaderConsts(%this)
{
   //echo($Sim::time - %this.timeStart);
   //echo(%this.timeConst);
   %this.setShaderConst( "$refTime", $GravityPFX::refTime ); 
}


#1
09/01/2010 (10:57 am)
I would like to know that, too!
Anybody?
#2
09/02/2010 (4:24 am)
@Deepscratch - How you have this split up right now is incorrect.

VS_GravityMap and PS_GravityMap is one pass of this effect.

VS_FinalBlend and PS_FinalBlend is the other.

So you need a PostEffect for the gravity map pass then a child PostEffect for the final blend with the scene.

So you would have gravityMap_V.hlsl and gravityMap_P.hlsl in the first PostEffect and finalBlend_V.hlsl and finalBlend_P.hlsl as your second PostEffect. In each of those you rename the function call to main.

I assume that the gravityMap pass would rendering to an offscreen target texture and the finalBlend pass reads it (see the GravityMapSampler).

Hopefully this gets you started down the right path.
#3
09/02/2010 (10:20 am)
wow, Tom,
thanks a ton, man, hell yeah, that really does help.
I'm still very new to shaders, kinda learning as I bash at it, and help from you guys is really apreciated.