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:
and these are my P and V shaders:
P shader:
and the V shader:
and this is my script file:
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 );
}About the author
email me at medan121@gmail.com
Recent Threads
#2
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.
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
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.
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.
Torque 3D Owner Alexander Krause
Coming soon...
Anybody?