D3 Materials

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Kalda
Posts: 47
Joined: Wed Aug 23, 2006 1:38 pm
Location: Prostejov, Czech Republic
Contact:

Post by Kalda »

As I said... It doesn't work. I have another (ocean) shader from ogre, but when I apply them, mesh will be invisible. Irrlicht writes any errors to console. It is same for another shaders...

Here is the shader code:

Pixel

Code: Select all

struct v2f {
	float4 Position  : POSITION;  // in clip space
	float3 rotMatrix1 : TEXCOORD0; // first row of the 3x3 transform from tangent to obj space
	float3 rotMatrix2 : TEXCOORD1; // second row of the 3x3 transform from tangent to obj space
	float3 rotMatrix3 : TEXCOORD2; // third row of the 3x3 transform from tangent to obj space

	float2 bumpCoord0 : TEXCOORD3;
	float2 bumpCoord1 : TEXCOORD4;
	float2 bumpCoord2 : TEXCOORD5;

	float3 eyeVector  : TEXCOORD6;
};


float4 main(v2f IN,
			uniform sampler2D NormalMap,
			uniform samplerCUBE EnvironmentMap,
			uniform float4 deepColor,
			uniform float4 shallowColor,
			uniform float4 reflectionColor,
			uniform float reflectionAmount,
			uniform float reflectionBlur,
			uniform float waterAmount,
			uniform float fresnelPower,
			uniform float fresnelBias,
			uniform float hdrMultiplier
			) : COLOR
{
	// sum normal maps
	// sample from 3 different points so no texture repetition is noticeable
    float4 t0 = tex2D(NormalMap, IN.bumpCoord0) * 2.0 - 1.0;
    float4 t1 = tex2D(NormalMap, IN.bumpCoord1) * 2.0 - 1.0;
    float4 t2 = tex2D(NormalMap, IN.bumpCoord2) * 2.0 - 1.0;
    float3 N = t0.xyz + t1.xyz + t2.xyz;

    float3x3 m; // tangent to world matrix
    m[0] = IN.rotMatrix1;
    m[1] = IN.rotMatrix2;
    m[2] = IN.rotMatrix3;

    N = normalize( mul( N, m ) );

	// reflection
    float3 E = normalize(IN.eyeVector);
    float4 R;
    R.xyz = reflect(E, N);
    // Ogre conversion for cube map lookup
    R.z = -R.z;
    R.w = reflectionBlur;
    float4 reflection = texCUBEbias(EnvironmentMap, R);
    // cheap hdr effect
    reflection.rgb *= (reflection.r + reflection.g + reflection.b) * hdrMultiplier;

	// fresnel
    float facing = 1.0 - max(dot(-E, N), 0);
    float fresnel = saturate(fresnelBias + pow(facing, fresnelPower));

    float4 waterColor = lerp(shallowColor, deepColor, facing) * waterAmount;

    reflection = lerp(waterColor,  reflection * reflectionColor, fresnel) * reflectionAmount;
    return waterColor + reflection;
}
Vertex:

Code: Select all

/*********************************************************************NVMH3****
Copyright NVIDIA Corporation 2003
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.


Comments:
	Simple ocean shader with animated bump map and geometric waves
	Based partly on "Effective Water Simulation From Physical Models", GPU Gems

11 Aug 05: heavily modified by Jeff Doyle (nfz) for Ogre

******************************************************************************/

struct a2v {
	float4 Position : POSITION;   // in object space
	float2 TexCoord : TEXCOORD0;
};

struct v2f {
	float4 Position : POSITION;  // in clip space
	float3 rotMatrix1 : TEXCOORD0; // first row of the 3x3 transform from tangent to obj space
	float3 rotMatrix2 : TEXCOORD1; // second row of the 3x3 transform from tangent to obj space
	float3 rotMatrix3 : TEXCOORD2; // third row of the 3x3 transform from tangent to obj space

	float2 bumpCoord0 : TEXCOORD3;
	float2 bumpCoord1 : TEXCOORD4;
	float2 bumpCoord2 : TEXCOORD5;

	float3 eyeVector : TEXCOORD6;
};

// wave functions

struct Wave {
  float freq;  // 2*PI / wavelength
  float amp;   // amplitude
  float phase; // speed * 2*PI / wavelength
  float2 dir;
};

float4 main(a2v IN,
		uniform float4x4 WorldViewProj,
		uniform float3 eyePosition,
		uniform float BumpScale,
		uniform float2 textureScale,
		uniform float2 bumpSpeed,
		uniform float time,
		uniform float waveFreq,
		uniform float waveAmp
        ) : POSITION
{
	v2f OUT;

	#define NWAVES 2
	Wave wave[NWAVES] = {
		{ 1.0, 1.0, 0.5, float2(-1, 0) },
		{ 2.0, 0.5, 1.7, float2(-0.7, 0.7) }
	};

    wave[0].freq = waveFreq;
    wave[0].amp = waveAmp;

    wave[1].freq = waveFreq * 3.0;
    wave[1].amp = waveAmp * 0.33;

    float4 P = IN.Position;

	// sum waves
	float ddx = 0.0, ddy = 0.0;
	float deriv;
	float angle;

	// wave synthesis using two sine waves at different frequencies and phase shift
	for(int i = 0; i<NWAVES; ++i)
	{
		angle = dot(wave[i].dir, P.xz) * wave[i].freq + time * wave[i].phase;
		P.y += wave[i].amp * sin( angle );
		// calculate derivate of wave function
		deriv = wave[i].freq * wave[i].amp * cos(angle);
		ddx -= deriv * wave[i].dir.x;
		ddy -= deriv * wave[i].dir.y;
	}

	// compute the 3x3 tranform from tangent space to object space
	// first rows are the tangent and binormal scaled by the bump scale

	OUT.rotMatrix1.xyz = BumpScale * normalize(float3(1, ddy, 0)); // Binormal
	OUT.rotMatrix2.xyz = BumpScale * normalize(float3(0, ddx, 1)); // Tangent
	OUT.rotMatrix3.xyz = normalize(float3(ddx, 1, ddy)); // Normal

	OUT.Position = mul(WorldViewProj, P);

	// calculate texture coordinates for normal map lookup
	OUT.bumpCoord0.xy = IN.TexCoord*textureScale + time * bumpSpeed;
	OUT.bumpCoord1.xy = IN.TexCoord*textureScale * 2.0 + time * bumpSpeed * 4.0;
	OUT.bumpCoord2.xy = IN.TexCoord*textureScale * 4.0 + time * bumpSpeed * 8.0;

	OUT.eyeVector = P.xyz - eyePosition; // eye position in vertex space
	return OUT.Position;
}

Kalda
Posts: 47
Joined: Wed Aug 23, 2006 1:38 pm
Location: Prostejov, Czech Republic
Contact:

Post by Kalda »

necroMonger
Posts: 5
Joined: Mon Jun 11, 2007 3:36 am

Post by necroMonger »

I don't understand why there are problems... Everything seem fine, but eitherwise I would think that OGRE might use some extra specifications you might missed (for instance I've read that models are loaded only from a .cfg file in OGRE, what else could a cfg file contain regarding material shaders?)

I will look furthermore into it the next 2 days, as I am very interested myself in using shaders for my game. If have made any progress I will give some tips. However I would like some advice regarding this issue from an experienced Irrlicht user. A good place to start is the Irrlicht demo "Per pixel lighting" as it features a cool parallax mapping shader. :D
Saturn
Posts: 418
Joined: Mon Sep 25, 2006 5:58 pm

Post by Saturn »

necroMonger wrote:I don't understand why there are problems... Everything seem fine, but eitherwise I would think that OGRE might use some extra specifications you might missed (for instance I've read that models are loaded only from a .cfg file in OGRE, what else could a cfg file contain regarding material shaders?)
Ogre doesn't need cfg files for loading meshes. In fact it doesn't need any cfg files at all.
Kalda wrote:Irrlicht writes any errors to console. It is same for another shaders...
Kalda, what "any errors" exactly are written? Or is there a "not" missing?

What does your shader callback look like?
Kalda
Posts: 47
Joined: Wed Aug 23, 2006 1:38 pm
Location: Prostejov, Czech Republic
Contact:

Post by Kalda »

Code: Select all

video::IVideoDriver* driver = services->getVideoDriver();
		float p[4] = {0};

		p[0] = 0.2f;
		//services->setVertexShaderConstant("$BumpScale",p,1);

		p[0] = 25.0f;
		p[1] = 26.0f;
		//services->setVertexShaderConstant("$textureScale",p,2);

		p[0] = 0.015f;
		p[1] = 0.005f;
		//services->setVertexShaderConstant("$bumpSpeed",p,2);

		core::matrix4 worldViewProj;
		worldViewProj = driver->getTransform(video::ETS_PROJECTION);			
		worldViewProj *= driver->getTransform(video::ETS_VIEW);
		worldViewProj *= driver->getTransform(video::ETS_WORLD);

		services->setVertexShaderConstant("$WorldViewProj", worldViewProj.pointer(), 16);

		core::vector3df pos;
		if(g_cam)
		{
			pos = g_cam->getPosition();
			p[0] = pos.X;
			p[1] = pos.Y;
			p[2] = pos.Z;

			services->setVertexShaderConstant("$eyePosition",p,3);
		}

		p[0] = (float)GetTickCount();
		services->setVertexShaderConstant("$time",p,1);

		p[0] = 0.028f;
		services->setVertexShaderConstant("$waveFreq",p,1);

		p[0] = 1.8f;
		services->setVertexShaderConstant("$waveAmp",p,1);

		p[0] = 0.0f;
		p[1] = 0.3f;
		p[2] = 0.5f;
		p[3] = 1.0f;
		services->setPixelShaderConstant("$deepColor",p,4);

		p[0] = 0.0f;
		p[1] = 1.0f;
		p[2] = 1.0f;
		p[3] = 1.0f;
		services->setPixelShaderConstant("$shallowColor",p,4);

		p[0] = 0.95f;
		p[1] = 1.0f;
		p[2] = 1.0f;
		p[3] = 1.0f;
		services->setPixelShaderConstant("$reflectionColor",p,4);

		p[0] = 1.0f;
		services->setPixelShaderConstant("$reflectionAmount",p,1);

		p[0] = 0.001f;
		services->setPixelShaderConstant("$reflectionBlur",p,1);

		p[0] = 0.3f;
		services->setPixelShaderConstant("$waterAmount",p,1);

		p[0] = 5.0f;
		services->setPixelShaderConstant("$fresnelPower",p,1);

		p[0] = 0.328f;
		services->setPixelShaderConstant("$fresnelBias",p,1);

		p[0] = 0.471f;
		services->setPixelShaderConstant("$hdrMultiplier",p,1);
But there is second problem. services->setVertexShaderConstant("$eyePosition",p,3); writes "variable not found"
spooky_paul
Posts: 16
Joined: Sun Nov 26, 2006 5:12 pm
Location: Romania

Post by spooky_paul »

Saturn wrote: Ogre doesn't need cfg files for loading meshes. In fact it doesn't need any cfg files at all.
actually ogre does use .cfg files. resource paths and terrain definitions are stored in such files
necroMonger wrote:OGRE might use some extra specifications you might missed
in ogre each fragment/vertex shader you use it is defined in a material script, maybe in there is some additional info

what i do not understand why do you refuse to use nvidia`s shader library. there is in there a perfect ocean shader example that it is not binded to any other rendering engine
Saturn
Posts: 418
Joined: Mon Sep 25, 2006 5:58 pm

Post by Saturn »

spooky_paul wrote:
Saturn wrote: Ogre doesn't need cfg files for loading meshes. In fact it doesn't need any cfg files at all.
actually ogre does use .cfg files. resource paths and terrain definitions are stored in such files
Ogre can't read resource.cfg files itself, this is solely for samples, they are parsed by the example framework, not by ogre itself. And everything that can be done in a terrain.cfg can be done in code. It doesn't need cfg files at all. :)
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Maybe my shadow mapping demo is relevant :wink:

http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=22225

I will release some source on how to implement this when I have time.
spooky_paul
Posts: 16
Joined: Sun Nov 26, 2006 5:12 pm
Location: Romania

Post by spooky_paul »

Saturn wrote: Ogre can't read resource.cfg files itself, this is solely for samples, they are parsed by the example framework, not by ogre itself. And everything that can be done in a terrain.cfg can be done in code. It doesn't need cfg files at all. :)
i didnt stated that ogre is dependent on cfg files. i said that it uses them :p
Post Reply