• Advertisement
Sign in to follow this  

Flame.fx (FIRE animation) - - SOLVED

This topic is 4756 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi friend! I'm here with a new problem!!! I'm trying to use NVIDIA FX file Flame.fx in my game, but I can't find a good solution to load and use this effect... I think that the problem is about some missing stage or some other little thing... The .FX file is this:
/*
	Volumetric flame effect
	based on Yury Uralsky's "Volumetric Fire"
	http://www.cgshaders.org/shaders/show.php?id=39
	
	This revolves a cross section of a flame image around the Y axis to
	produce a cylindrical volume, and then perturbs the texture coordinates
	with 4 octaves of animated 3D procedural noise to produce the flame effect.
*/

string XFile = "slices_10y.x";
string description = "3D Flame";

float Script : STANDARDSGLOBAL <
    string UIWidget = "none";
    string ScriptClass = "object";
    string ScriptOrder = "standard";
    string ScriptOutput = "color";
    string Script = "Technique=ps20;";
> = 0.8;

float ticks : Time
<
 string units = "sec";
>;

/************* TWEAKABLES **************/

float noiseFreq
<
    string UIWidget = "slider";
    float UIMin = 0.0; float UIMax = 1.0; float UIStep = 0.01;
> = 0.1;

float noiseStrength
<
    string UIWidget = "slider";
    float UIMin = 0.0; float UIMax = 5.0; float UIStep = 0.01;
> = 1.0;

float timeScale
<
    string UIWidget = "slider";
    float UIMin = 0.0; float UIMax = 1.0; float UIStep = 0.01;
> = 1.0;

float3 noiseScale = { 0.5, 0.5, 0.5 };
float3 noiseAnim = { 0.4, -1.9, 0.8 };

float4 flameColor = { 0.3, 0.2, 0.2, 0.8 };
float3 flameScale = { 0.25, -0.18, 0.12};
float3 flameTrans = { 0.0, -0.1, 0.0 };

// Textures

#define VOLUME_SIZE 32

texture noiseTexture
<
    string Name = "noiseL8_32x32x32.dds";
    string ResourceType = "3D";
	string function = "GenerateNoise1f";
	float3 Dimensions = { VOLUME_SIZE, VOLUME_SIZE, VOLUME_SIZE};
>;

texture flameTexture
<
    string ResourceName = "flame.png";
    string ResourceType = "2D";
>;

// Vector-valued noise
float4 GenerateNoise4f(float3 Pos : POSITION) : COLOR
{
	float4 c;
	float3 P = Pos*VOLUME_SIZE;
	c.r = noise(P);
	c.g = noise(P + float3(11, 17, 23));
	c.b = noise(P + float3(57, 93, 65));
	c.a = noise(P + float3(77, 15, 111));
//	return c*0.5+0.5;
	return abs(c);
}

// Scalar noise
float GenerateNoise1f(float3 Pos : POSITION) : COLOR
{
	float3 P = Pos*VOLUME_SIZE;
//	return noise(P)*0.5+0.5;
	return abs(noise(P));
}

// Tracked matricies
float4x4 wvp : WorldViewProjection;
float4x4 world : World;

// Structures
struct appdata {
    float3 Position	: POSITION;
    float4 UV		: TEXCOORD0;
    float4 Tangent	: TANGENT0;
    float4 Binormal	: BINORMAL0;
    float4 Normal	: NORMAL;
};

struct vertexOutput {
    float4 HPosition	: POSITION;
    float3 NoisePos     : TEXCOORD0;
    float3 FlamePos     : TEXCOORD1;
    float2 UV           : TEXCOORD2;
};

// Vertex shader
vertexOutput flameVS(appdata IN,
					uniform float4x4 WorldViewProj,
					uniform float4x4 World,
					uniform float3 noiseScale,					
					uniform float noiseFreq,
					uniform float3 noiseAnim,
					uniform float3 flameScale,
					uniform float3 flameTrans,
					uniform float timeScale
					)
{
    vertexOutput OUT;
    float4 objPos = float4(IN.Position.x,IN.Position.y,IN.Position.z,1.0);
    float3 worldPos = mul(objPos, World).xyz;
 
    OUT.HPosition = mul(objPos, WorldViewProj);
    float time = fmod(ticks, 10.0);	// avoid large texcoords
    OUT.NoisePos = worldPos*noiseScale*noiseFreq + time*timeScale*noiseAnim;
	OUT.FlamePos = worldPos*flameScale + flameTrans;
	
	OUT.UV = IN.UV;
    return OUT;
}

// Pixel shaders
half4 noise3D(uniform sampler3D NoiseMap, float3 P)
{
//	return tex3D(NoiseMap, P)*2-1;
	return tex3D(NoiseMap, P);
}

half4 turbulence4(uniform sampler3D NoiseMap, float3 P)
{
	half4 sum = noise3D(NoiseMap, P)*0.5 +
 				noise3D(NoiseMap, P*2)*0.25 +
 				noise3D(NoiseMap, P*4)*0.125 +
				noise3D(NoiseMap, P*8)*0.0625;
	return sum;
}

half4 flamePS(vertexOutput IN,
			  uniform sampler3D NoiseMap,
			  uniform sampler2D FlameTex,
			  uniform half noiseStrength,
			  uniform half4 flameColor
			  ) : COLOR
{
//	return tex3D(NoiseMap,IN.NoisePos) * flameColor;
//  return turbulence4(NoiseMap, IN.NoisePos) * flameColor;

	half2 uv;
	uv.x = length(IN.FlamePos.xz);	// radial distance in XZ plane
	uv.y = IN.FlamePos.y;
	
//	uv.y += turbulence4(NoiseMap, IN.NoisePos) * noiseStrength;
	uv.y += turbulence4(NoiseMap, IN.NoisePos) * noiseStrength / uv.x;

	return tex2D(FlameTex, uv) * flameColor;
}

/****************************************************/
/********** SAMPLERS ********************************/
/****************************************************/

sampler3D noiseTextureSampler = sampler_state
{
	Texture = <noiseTexture>;
	MinFilter = Linear;
	MagFilter = Linear;
	MipFilter = Linear;
};

sampler2D flameTextureSampler = sampler_state
{
	Texture = <flameTexture>;
	MinFilter = Linear;
	MagFilter = Linear;
	MipFilter = Linear;
	AddressU = Clamp;
	AddressV = Clamp;	
};


/****************************************************/
/********** TECHNIQUES ******************************/
/****************************************************/

technique ps20 <
	string Script = "Pass=p1d;";
> {
    pass p1d <
		string Script = "Draw=geometry;";
    > {		
	VertexShader = compile vs_1_1 flameVS(wvp, world,
										  noiseScale, noiseFreq, noiseAnim,
										  flameScale, flameTrans, timeScale
										  );

	ZEnable = true;
	ZWriteEnable = true;
	CullMode = None;

	AlphaBlendEnable = true;
	BlendOp = Add;		
	SrcBlend = One;
	DestBlend = One;
	
	PixelShader = compile ps_2_0 flamePS(noiseTextureSampler, flameTextureSampler, noiseStrength, flameColor);
    }
}

/***************************** eof ***/









I've loaded my effect and passed to it values and matrices...
	dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
	dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
	dwShaderFlags |= D3DXSHADER_NO_PRESHADER;

	if( FAILED( D3DXCreateEffectFromFile( g_pD3DDevice, PathFlameEffect, 
					NULL, // CONST D3DXMACRO* pDefines,
					NULL, // LPD3DXINCLUDE pInclude,
					dwShaderFlags, NULL, &g_pEffect, NULL )))
					OutputDebugString( "Error in Flame_OK.fx\n" );

	D3DXCreateTextureFromFile(g_pD3DDevice, PathFlameTexture1 , &g_FlameTexture1 );
	D3DXCreateTextureFromFile(g_pD3DDevice, PathFlameTexture2 , &g_FlameTexture2 );


		D3DXHANDLE Tecn = g_pEffect->GetTechnique( 0 );
		if (FAILED(g_pEffect->SetTechnique(Tecn)))
			OutputDebugString( "Impossibile settare la Technique ps20\n" );

		g_pEffect->SetFloat( "ticks", (float)QuantoVeloce );
		g_pEffect->SetFloat( "noiseFreq", 0.1f );
		g_pEffect->SetFloat( "noiseStrength", 1.0f );
		g_pEffect->SetFloat( "timeScale", 1.0f );

		g_pEffect->SetValue( "noiseScale", D3DXVECTOR3(0.5, 0.5, 0.5), sizeof(D3DXVECTOR3) );
		g_pEffect->SetValue( "noiseAnim", D3DXVECTOR3(0.4, -1.9, 0.8), sizeof(D3DXVECTOR3) );

		g_pEffect->SetValue( "flameColor", D3DXVECTOR4(0.3, 0.2, 0.2, 1.0), sizeof(D3DXVECTOR4) );
		g_pEffect->SetValue( "flameScale", D3DXVECTOR3(0.25, -0.18, 0.12), sizeof(D3DXVECTOR3) );
		g_pEffect->SetValue( "flameTrans", D3DXVECTOR3(0.0, -0.1, 0.0), sizeof(D3DXVECTOR3) );

		
		g_pD3DDevice->GetTransform( D3DTS_WORLD, &mWorld );
		g_pD3DDevice->GetTransform( D3DTS_VIEW, &mView );
		g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &mProj );
		mWorldViewProjection = mWorld * mView * mProj;

		g_pEffect->SetMatrix( "wvp", &mWorldViewProjection );
		g_pEffect->SetMatrix( "world", &mWorld );
		
		if( FAILED( g_pEffect->SetTexture( "noiseTexture", g_FlameTexture1 ) ))
			OutputDebugString( "Impossibile assegnare noiseTexture\n" );

		if( FAILED( g_pEffect->SetTexture( "flameTexture", g_FlameTexture2 ) ))
			OutputDebugString( "Impossibile assegnare flameTexture\n" );









and then I run the effect in the usual way:
    UINT cPasses=0; 
	// Apply the technique contained in the effect 
	g_pEffect->Begin(&cPasses, 0);

	for (iPass = 0; iPass < cPasses; iPass++)
	{

	    g_pEffect->BeginPass(iPass);
	
		g_pD3DDevice->SetTexture( 0, g_FlameTexture1 );		
		g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
		g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
		g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );

		g_pD3DDevice->SetTexture( 0, g_FlameTexture2 );
		g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
		g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
		g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
		g_pD3DDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
		g_pD3DDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );

		g_pD3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
		g_pD3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
		g_pD3DDevice->SetRenderState( D3DRS_CULLMODE,  D3DCULL_NONE );
		g_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE , TRUE );
		g_pD3DDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
		g_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
		g_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

		g_pEffect->CommitChanges();

	    // Render the mesh with the applied technique
		Flame.Update();
		g_FlameMesh->MeshData.pMesh->DrawSubset(0);
	
	    g_pEffect->EndPass();
	}
	g_pEffect->End();









After that, when I run my app, I could only see my "g_FlameMesh" onto the screen with only one STATIC texture applied without any animated effect... Where is the problem in my code?! I've missed something?! Where I'm wrong?! Is it a bad way to use effect files?! THANKS for help!!! Bye, [Edited by - GENTS on January 9, 2005 10:47:57 AM]

Share this post


Link to post
Share on other sites
Advertisement
You need to increment the time and assign it to the "ticks" variable. I don't see that you are doing this in your posted code.

Share this post


Link to post
Share on other sites
I've added the code you said but it still doesn't work...

Seems I need something strange as SamplerStage or TextureStage or probably I miss something important...

Help me please!!! ^__^

Byez,

Share this post


Link to post
Share on other sites
Could it be an error in VERTEX declaration of my mesh or in device's FVF ?!?

How should I declare VERTEX and FVF for my mesh?!

(I've undeclared anything special for VERTEX or FVF 'cause in my .X file the Effect result just applied so, I think, vertex information should be correct)

I still can't find a working solution!!!

Share this post


Link to post
Share on other sites
Hi,

Remove all the code that changes the device states inside the BeginPass/Endpass. Your code should look like:

//Load your effect, textures and meshes. Do it as in your code... then set the parameters that will never change for this effect during this execution

g_pEffect->SetFloat( "noiseFreq", 0.1f );
g_pEffect->SetFloat( "noiseStrength", 1.0f );
g_pEffect->SetFloat( "timeScale", 1.0f );

g_pEffect->SetValue( "noiseScale", D3DXVECTOR3(0.5, 0.5, 0.5), sizeof(D3DXVECTOR3) );
g_pEffect->SetValue( "noiseAnim", D3DXVECTOR3(0.4, -1.9, 0.8), sizeof(D3DXVECTOR3) );

g_pEffect->SetValue( "flameColor", D3DXVECTOR4(0.3, 0.2, 0.2, 1.0), sizeof(D3DXVECTOR4) );
g_pEffect->SetValue( "flameScale", D3DXVECTOR3(0.25, -0.18, 0.12), sizeof(D3DXVECTOR3) );
g_pEffect->SetValue( "flameTrans", D3DXVECTOR3(0.0, -0.1, 0.0), sizeof(D3DXVECTOR3) );

if( FAILED( g_pEffect->SetTexture( "noiseTexture", g_FlameTexture1 ) ))
OutputDebugString( "Impossibile assegnare noiseTexture\n" );

if( FAILED( g_pEffect->SetTexture( "flameTexture", g_FlameTexture2 ) ))
OutputDebugString( "Impossibile assegnare flameTexture\n" );



//Once everyting is loaded, use the windows loop to call a render function
void Render()
{
//Compute the current time
time=GetTickCount();

//Clear your color and back buffer.

//Update the effect params that should be updated each frame

g_pEffect->SetFloat( "ticks", (float)QuantoVeloce );
g_pD3DDevice->GetTransform( D3DTS_WORLD, &mWorld );
g_pD3DDevice->GetTransform( D3DTS_VIEW, &mView );
g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &mProj );
mWorldViewProjection = mWorld * mView * mProj;
g_pEffect->SetMatrix( "wvp", &mWorldViewProjection );
g_pEffect->SetMatrix( "world", &mWorld );


//Call the render loop, no additional changes required because shading is done in PS2.0
UINT cPasses=0;
// Apply the technique contained in the effect
g_pEffect->Begin(&cPasses, 0);
for (iPass = 0; iPass < cPasses; iPass++)
{
g_FlameMesh->MeshData.pMesh->DrawSubset(0);
g_pEffect->EndPass();
}
g_pEffect->End();

//Flip


}



Try this

Luck!
Guimo

Share this post


Link to post
Share on other sites
I've tried your code, but it still doesn't work!!!

This is my code:

INIT FUNCTION()

D3DXCreateTextureFromFile(g_pD3DDevice, PathFlameTexture1 , &g_FlameTexture1 );
D3DXCreateTextureFromFile(g_pD3DDevice, PathFlameTexture2 , &g_FlameTexture2 );

// Load the collection of meshes used for demo
LoadMesh(&g_FlameMesh, g_pD3DDevice, PathFlames, "..\\Data\\flame\\" );
Flame.AddObject( g_FlameMesh );
Flame.ScaleMesh( g_FlameMesh, 10.0f );
Flame.SetPosition( -350, 200, -10 );
Flame.SetYaw( pi );
Flame.SetPitch( pi/3 );

dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
dwShaderFlags |= D3DXSHADER_NO_PRESHADER;

if( FAILED( D3DXCreateEffectFromFile( g_pD3DDevice, PathFlameEffect,
NULL, // CONST D3DXMACRO* pDefines,
NULL, // LPD3DXINCLUDE pInclude,
dwShaderFlags, NULL, &g_pEffect, NULL )))
OutputDebugString( "Errore nel caricamento del file Flame_OK.fx\n" );

D3DXHANDLE Tecn = g_pEffect->GetTechnique( 0 );
if (FAILED(g_pEffect->SetTechnique(Tecn)))
OutputDebugString( "Impossibile settare la Technique ps20\n" );

g_pEffect->SetFloat( "noiseFreq", 0.1f );
g_pEffect->SetFloat( "noiseStrength", 1.0f );
g_pEffect->SetFloat( "timeScale", 1.0f );

g_pEffect->SetValue( "noiseScale", D3DXVECTOR3(0.5, 0.5, 0.5), sizeof(D3DXVECTOR3) );
g_pEffect->SetValue( "noiseAnim", D3DXVECTOR3(0.4, -1.9, 0.8), sizeof(D3DXVECTOR3) );

g_pEffect->SetValue( "flameColor", D3DXVECTOR4(0.3, 0.2, 0.2, 1.0), sizeof(D3DXVECTOR4) );
g_pEffect->SetValue( "flameScale", D3DXVECTOR3(0.25, -0.18, 0.12), sizeof(D3DXVECTOR3) );
g_pEffect->SetValue( "flameTrans", D3DXVECTOR3(0.0, -0.1, 0.0), sizeof(D3DXVECTOR3) );

if( FAILED( g_pEffect->SetTexture( "noiseTexture", g_FlameTexture1 ) ))
OutputDebugString( "Impossibile assegnare noiseTexture\n" );

if( FAILED( g_pEffect->SetTexture( "flameTexture", g_FlameTexture2 ) ))
OutputDebugString( "Impossibile assegnare flameTexture\n" );



RENDER FUNCTION()

ThisTime = timeGetTime();

Flame.Update();

g_pEffect->SetFloat( "ticks", (float)ThisTime );
g_pD3DDevice->GetTransform( D3DTS_WORLD, &mWorld );
g_pD3DDevice->GetTransform( D3DTS_VIEW, &mView );
g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &mProj );
mWorldViewProjection = mWorld * mView * mProj;

g_pEffect->SetMatrix( "wvp", &mWorldViewProjection );
g_pEffect->SetMatrix( "world", &mWorld );


UINT cPasses=0;
// Apply the technique contained in the effect
g_pEffect->Begin(&cPasses, 0);

for (iPass = 0; iPass < cPasses; iPass++)
{

g_pEffect->BeginPass(iPass);

// Render the mesh with the applied technique
g_FlameMesh->MeshData.pMesh->DrawSubset(0);

g_pEffect->EndPass();
}
g_pEffect->End();



Result is always the same...

I'm beginning to think that I load in a wrong way the mesh undeclaring Vertex type or FVF...

THANKS for help!!!

Share this post


Link to post
Share on other sites
Even if I change color (flameColor) my g_FlameMesh still remains white!!!

How can I solve all my problems?!

[Edited by - GENTS on January 6, 2005 9:39:54 AM]

Share this post


Link to post
Share on other sites
MMMMMMMM... have you tried FXComposer in order to get correct values for the parameters? Maybe some colors aren't ok.

Also, do do you have the flame.png file. Some people reported it missing. I'd suggest you to convert the flame FX into another format like flame.png and add some alpha information in order to mask transparent areas (black areas).

Also, I'd suggest to use FX default values while you are testing it.

Luck!
Guimo

Share this post


Link to post
Share on other sites
I've used the oeriginal FX file and a modified one with all original textures:

flame.png
noiseL8_32x32x32.dds

I've seen that in FX composer it works well, but in the EffectEdit doesn't...

I've also tried to change XFile parameter in the FX file, but results are the same...

I can't get out!!!

THANKS ^__^

Share this post


Link to post
Share on other sites
Have you got a working appz using this FLAME.fx effect?!

Could someone send me or post here a working version of using this effect file?! [gents@email.it]

THANKS!!!

Share this post


Link to post
Share on other sites
Hi,

I've used this effect to render the flames and burning coals inside the flame (with a simple change of texture). I cant send the code as render portions are inside of my engine.

FXComposer effects wont work in Effect Edit. Effects arent universal. Any app that tres to use an effect must understand the effect parameters. Thats why the semantics are used, to give a hint to the host app about how to use it. But if the app doesn't understand the semntics, the effect can't be used.

I'd suggest you try other simpler effects before trying this one. Maybe one that deforms the objects using time. Then try some time moving texture coordinates. After that you can try loading the flame effect.

Luck!
Guimo

Share this post


Link to post
Share on other sites
OK...
You've make me happy helping me, but please don't leave me alone now ^__^

I've added my ticks and I've tested, the increment is regular, but I can't see anything new on my screen...

I'm trying any type of solution, but I can't understand why it doesn't work for me... I've changed mesh reference, I've tried a lot of parameters, I've debugged my application, everything seems ok but my screen is always the same...

I've tried with tons of other simpler effects, but seems that this one doesn't works... In FX Composer it's ok, works well with original textures, other ones, or with original parameters or changed...

In my appz I could always watch at a white or transparent quad without any effect on it...

But code seems ok...

Where am I wrong?! Where is the bug to fix in my code?!

Should I not use an .X file to render effect on?! Should I use a VertexBuffer filled in a strange way?!

I could not understand...

Please help me! ^__^

Share this post


Link to post
Share on other sites
Hi,

I'd suggest:

a. Leave the effect default values. Those value are set the moment the effect is compiled and will never change so no need to set them, that is, delete this lines.

g_pEffect->SetFloat( "ticks", (float)QuantoVeloce );
g_pEffect->SetFloat( "noiseFreq", 0.1f );
g_pEffect->SetFloat( "noiseStrength", 1.0f );
g_pEffect->SetFloat( "timeScale", 1.0f );

g_pEffect->SetValue( "noiseScale", D3DXVECTOR3(0.5, 0.5, 0.5), sizeof(D3DXVECTOR3) );
g_pEffect->SetValue( "noiseAnim", D3DXVECTOR3(0.4, -1.9, 0.8), sizeof(D3DXVECTOR3) );

g_pEffect->SetValue( "flameColor", D3DXVECTOR4(0.3, 0.2, 0.2, 1.0), sizeof(D3DXVECTOR4) );
g_pEffect->SetValue( "flameScale", D3DXVECTOR3(0.25, -0.18, 0.12), sizeof(D3DXVECTOR3) );
g_pEffect->SetValue( "flameTrans", D3DXVECTOR3(0.0, -0.1, 0.0), sizeof(D3DXVECTOR3) );


b. Notice that the only parameters without a default value are:
texture noiseTexture;
texture flameTexture;

float ticks : Time
<
string units = "sec";
>;

float4x4 wvp : WorldViewProjection;
float4x4 world : World;

From those, the first two can be set only once when you load the effect (as you already do). The other three must change each frame. Also, the time parameter has an annotation that tells you that this parameter should receive seconds (not milliseconds... forgot that before). But if you check this line in the VS:
OUT.NoisePos = worldPos*noiseScale*noiseFreq + time*timeScale*noiseAnim;

You can see that the time parameter is multiplied by the timeScale parameter. So you can send milliseconds but change the time scale appropiately when you load the effect. In case you send millisecond, timeScale probably should be set to 0.001f. Your choice.

The matrices should be changes each frame before you render the effect. And it should be fine or you wouldnt be seeing the quad at all.

c. Third. Check the required input:
vertexOutput flameVS(appdata IN,
uniform float4x4 WorldViewProj,
uniform float4x4 World,
uniform float3 noiseScale,
uniform float noiseFreq,
uniform float3 noiseAnim,
uniform float3 flameScale,
uniform float3 flameTrans,
uniform float timeScale
)

If you are using default values, and you have set time and matrices, then all the uniform parameters are already set. In fact, you may just simplify this line to:
vertexOutput flameVS(appdata IN)

So, you should check the required input here:
struct appdata {
float3 Position : POSITION;
float4 UV : TEXCOORD0;
float4 Tangent : TANGENT0;
float4 Binormal : BINORMAL0;
float4 Normal : NORMAL;
};

So, you must seee that your vertices should have all this information (OR MORE) but no less. In case od a quad it is really simple to set this values in your mesh at creation time. Position ad UV values are simple (set UV as the usual 0,1 values). The Tangent, binormal and normal are vectors that define the space over you triangle. So just compute the normal to the plane (easy math), the tangent to the plane (easier math) and the binormal (the cross vector from the other two), and set those values. As your plane is flat, just set the same values to all your points. Thats all.

I have nothing else to comment. But if you manage to do it, it is the same basic configuration to create bump, waves, water and many of the special effects in FXComposer.

Luck!
Guimo

Share this post


Link to post
Share on other sites
Only one last thing...

How do you think that must be FLAME_FVF ?!?!

THANKS

Share this post


Link to post
Share on other sites
I've tried also creating a VertexBuffer filled with data as Guimo said, but it still doesn't works...

I've seen that an essential part that I don't know how fill is the FVF, so I've arranged with getFVF() from my g_FlameMesh...

But it doesn't work...

Where is the problem?!

THANKS for help!!!!

Share this post


Link to post
Share on other sites
Quote:
Original post by GENTS
I've seen that an essential part that I don't know how fill is the FVF, so I've arranged with getFVF() from my g_FlameMesh...


(1) You need to create a Vertex Declaration. FVF's are a thing of the past, and were used for the fixed-function-pipeline. Now, we use the IDirect3DVertexDeclaration9 to describe to the vertex shader what the structure of our vertex buffer looks like. Read my post here to see how this is commonly done. Remember, the structure of your vertex buffer needs to match your vertex declaration, and your vertex declaration needs to match the input of your vertex shader.

(2) I'm not so sure this effect was meant to be applied to a 3D mesh. It might have been designed to be rendered to a flat plane, not complex geometry. This makes sense, because it is simply drawing flames on the object dynamically. Most shaders that have post-processing effects like this were meant for 2D sprites.

(3) If you keep encountering problems, try debugging this shader (this is an extremely useful tool). Read this SDK page to find out how to use it.

Share this post


Link to post
Share on other sites
Ok I'll try with your suggests and then I'll tell you results

^__^

If I can't use my .X file mesh I'll create a single Vertex Buffer for my quad and then I'll re-try...

Thanks for hel an stay on-line for results...

^__^

Share this post


Link to post
Share on other sites
Ok that's my new code:

Declarations:

// Vertex shader declaration
D3DVERTEXELEMENT9 g_FlameMeshDecl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 },
{ 0, 44, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },
{ 0, 60, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
D3DDECL_END()
};

// the struct for flame verts
struct FLAMEVERT
{
D3DXVECTOR3 p;
D3DXVECTOR4 tex;
D3DXVECTOR4 t;
D3DXVECTOR4 b;
D3DXVECTOR4 n;
};

IDirect3DVertexDeclaration9 *g_FlameDecl = NULL;






Init()

// Create a big square for rendering flames
g_pD3DDevice->CreateVertexBuffer( 4*sizeof(FLAMEVERT),
D3DUSAGE_WRITEONLY, NULL,
D3DPOOL_MANAGED, &g_FlameVB, NULL );

// Set the size of the big square and fill its fields
FLAMEVERT* fv;
FLOAT fx = (FLOAT)200;
g_FlameVB->Lock( 0, 0, (void**)&fv, 0 );
fv[0].p = D3DXVECTOR3( -2*fx, fx, -fx );
fv[1].p = D3DXVECTOR3( -2*fx, 0, 0 );
fv[2].p = D3DXVECTOR3( -fx, fx, -fx );
fv[3].p = D3DXVECTOR3( -fx, 0, 0 );
fv[0].tex = D3DXVECTOR4( 0, 0, 0, 0 );
fv[1].tex = D3DXVECTOR4( 0, 1, 0, 1 );
fv[2].tex = D3DXVECTOR4( 1, 0, 1, 0 );
fv[3].tex = D3DXVECTOR4( 1, 1, 1, 1 );
fv[0].t = D3DXVECTOR4( 0, 1, 0, 0 );
fv[1].t = D3DXVECTOR4( 0, 1, 0, 0 );
fv[2].t = D3DXVECTOR4( 0, 1, 0, 0 );
fv[3].t = D3DXVECTOR4( 0, 1, 0, 0 );
fv[0].b = D3DXVECTOR4( 1, 0, 0, 0 );
fv[1].b = D3DXVECTOR4( 1, 0, 0, 0 );
fv[2].b = D3DXVECTOR4( 1, 0, 0, 0 );
fv[3].b = D3DXVECTOR4( 1, 0, 0, 0 );
fv[0].n = D3DXVECTOR4( 0, 0, 1, 0 );
fv[1].n = D3DXVECTOR4( 0, 0, 1, 0 );
fv[2].n = D3DXVECTOR4( 0, 0, 1, 0 );
fv[3].n = D3DXVECTOR4( 0, 0, 1, 0 );
g_FlameVB->Unlock();


// create effect file

LPD3DXBUFFER pBufferErrors = NULL;

if( FAILED( D3DXCreateEffectFromFile( g_pD3DDevice, PathFlameEffect,
NULL, // CONST D3DXMACRO* pDefines,
NULL, // LPD3DXINCLUDE pInclude,
dwShaderFlags, NULL, &g_pEffect, &pBufferErrors ))){
OutputDebugString( "Errore nel caricamento del file Flame.fx\n" );
LPVOID pCompilErrors = pBufferErrors->GetBufferPointer();
MessageBox(NULL, (const char*)pCompilErrors, "Fx Compile Error", MB_OK|MB_ICONEXCLAMATION);
}

//Set Technique, parameters, etc.

D3DXHANDLE Tecn = g_pEffect->GetTechnique( 0 );
if (FAILED(g_pEffect->SetTechnique(Tecn)))
OutputDebugString( "Impossibile settare la Technique ps20\n" );

if( FAILED( g_pEffect->SetFloat( "noiseFreq", 0.1f ) ))
OutputDebugString( "Impossibile assegnare noiseFreq\n" );
if( FAILED( g_pEffect->SetFloat( "noiseStrength", 1.0f ) ))
OutputDebugString( "Impossibile assegnare noiseStrength\n" );
if( FAILED( g_pEffect->SetFloat( "timeScale", 1.0f ) ))
OutputDebugString( "Impossibile assegnare timeScale\n" );

D3DXVECTOR3 noiseScale = D3DXVECTOR3(0.5, 0.5, 0.5);
D3DXVECTOR3 noiseAnim = D3DXVECTOR3(0.4, -1.9, 0.8);
if( FAILED( g_pEffect->SetValue( "noiseScale", noiseScale, sizeof(D3DXVECTOR3) ) ))
OutputDebugString( "Impossibile assegnare noiseScale\n" );
if( FAILED( g_pEffect->SetValue( "noiseAnim", noiseAnim, sizeof(D3DXVECTOR3) ) ))
OutputDebugString( "Impossibile assegnare noiseAnim\n" );

D3DXCOLOR flameColor = D3DXCOLOR(0.3, 0.2, 0.2, 1.0);
D3DXVECTOR3 flameScale = D3DXVECTOR3(0.25, -0.18, 0.12);
D3DXVECTOR3 flameTrans = D3DXVECTOR3(0.0, -0.1, 0.0);
if( FAILED( g_pEffect->SetValue( "flameColor", &flameColor, sizeof(D3DXCOLOR) ) ))
OutputDebugString( "Impossibile assegnare flameColor\n" );
if( FAILED( g_pEffect->SetValue( "flameScale", flameScale, sizeof(D3DXVECTOR3) ) ))
OutputDebugString( "Impossibile assegnare flameScale\n" );
if( FAILED( g_pEffect->SetValue( "flameTrans", flameTrans, sizeof(D3DXVECTOR3) ) ))
OutputDebugString( "Impossibile assegnare flameTrans\n" );

if( FAILED( g_pEffect->SetTexture( "noiseTexture", g_FlameTexture1 ) ))
OutputDebugString( "Impossibile assegnare noiseTexture\n" );

if( FAILED( g_pEffect->SetTexture( "flameTexture", g_FlameTexture2 ) ))
OutputDebugString( "Impossibile assegnare flameTexture\n" );







Render()

UINT cPasses=0;
// Apply the technique contained in the effect
if( SUCCEEDED( g_pEffect->SetTechnique("ps20") ) ){

ticks = (float)GetTickCount()/1000;

g_pEffect->SetFloat( "ticks", ticks );
g_pD3DDevice->GetTransform( D3DTS_WORLD, &mWorld );
g_pD3DDevice->GetTransform( D3DTS_VIEW, &mView );
g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &mProj );
mWorldViewProjection = mWorld * mView * mProj;

g_pEffect->SetMatrix( "wvp", &mWorldViewProjection );
g_pEffect->SetMatrix( "world", &mWorld );


g_pEffect->Begin(&cPasses, 0);
for (iPass = 0; iPass < cPasses; iPass++)
{
g_pEffect->BeginPass(iPass);

// Render the mesh with the applied technique
g_pEffect->GetVertexShader( "VertexShader", &g_FlameVS );
g_pD3DDevice->SetFVF(NULL);
g_pD3DDevice->SetVertexShader(g_FlameVS);
g_pD3DDevice->SetVertexDeclaration(g_FlameDecl);

g_pD3DDevice->SetStreamSource( 0, g_FlameVB, 0, sizeof(FLAMEVERT) );
g_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

g_pEffect->EndPass();
}
g_pEffect->End();

}






BUT IT STILL DOESN'T WORK!!!

Where is the new error/problem?!


This is the screen withOUT this code:

// Render the mesh with the applied technique
g_pEffect->GetVertexShader( "VertexShader", &g_FlameVS );
g_pD3DDevice->SetFVF(NULL);
g_pD3DDevice->SetVertexShader(g_FlameVS);
g_pD3DDevice->SetVertexDeclaration(g_FlameDecl);







and this is with:



Thanks for help!

[Edited by - GENTS on January 6, 2005 4:14:57 PM]

Share this post


Link to post
Share on other sites
You can set your d3d debug flag on and then it'll show you in the debug output
if there's something wrong with your vertex declaration. add this flag
in your preprocessor field: D3D_DEBUG_INFO
In your debug output window it will put a bunch of useful information in regards
to having dx set up correctly, and if your vertex declaration are correct.

- Oordeel

Share this post


Link to post
Share on other sites
You were right...

While debugging my appz find this error but I don't know how to avoid to that...

Direct3D9: Decl Validator: X281: (Element Error) (Decl Element [0]) Usage field contains value that is not a member of D3DDECLUSAGE. Value: 0x48. Aborting decl validation.
Direct3D9: (ERROR) :Failed to create vertex declaration

I think that my declaration was good:

// Vertex shader declaration
D3DVERTEXELEMENT9 g_FlameMeshDecl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 },
{ 0, 44, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },
{ 0, 60, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
D3DDECL_END()
};

Where it's wrong?!

It seems that is an invalid use of D3DDECLUSAGE_BINORMAL in position 0x48..
Could it be possible?!

Share this post


Link to post
Share on other sites
There is no good reason wor this error, so no replies?!

Thanks for help!

Share this post


Link to post
Share on other sites
Hi there,

in your last posted RENDER() function above...you try to set the technique for "ps20". Are you sure your graphics card supports PS/VS 2.0??

It would help if you add an "else" part to your "if (SUCCEED(...))" statement and throw an assert or something to see if it really works or not.
This brings up a possible solution why it works on FX Composer. I believe this tool has some kind of "fall-back" if one technique fails..
correct me if i'm wrong.

simply do a PS/VS version check somewhere after D3D has been initialized.

regrads,
- Christoph -

Share this post


Link to post
Share on other sites
Yes, my card supports PS_2.0 and VS_2.0 very well...

That's not the problem...

Seems that the problem is in the vertex declaration...


When I have to do that:

g_pD3DDevice->SetFVF(NULL);
g_pD3DDevice->SetVertexDeclaration(g_FlameDecl);

My vertex declaration isn't set cause failed due to error:

Direct3D9: Decl Validator: X281: (Element Error) (Decl Element [0]) Usage field contains value that is not a member of D3DDECLUSAGE. Value: 0x48. Aborting decl validation.
Direct3D9: (ERROR) :Failed to create vertex declaration

But It seems that my declaration was good... So I can't understand where is the problem...

Thanks for help...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement