Multi-pass shader!

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
Post Reply
chromdragon
Posts: 101
Joined: Wed Feb 15, 2006 4:22 pm
Location: RO

Multi-pass shader!

Post by chromdragon »

Just playing with multi-pass algorithms and I implement multi-pass lighting and add a new new shader callback type.

One light:
Image

Three lights:
Image

The new shader callback:

Code: Select all


Class NewShaderCallBack: public IShader
{
public:

	NewShaderCallBack()
	{
	}

	s32 Begin(void)
	{
		return 2;
	}

	void End(void)
	{
	}

	void BeginPass(s32 pass)
	{
		if (pass == 0)
		{
			float fpos[3];

			vector3df position = light->getPosition();
			fpos[0] = position.X;
			fpos[1] = position.Y;
			fpos[2] = position.Z;
			setFloatVec("light_position", fpos, 3);

			SColorf color = light->getLightData().DiffuseColor;
			fpos[0] = color.r;
			fpos[1] = color.g;
			fpos[2] = color.b;
			setFloatVec("light_diffuse", fpos, 3);

			setFloat("light_r", light->getLightData().Radius);
		}
		else if (pass == 1)
		{
			float fpos[3];

			vector3df position = light2->getPosition();
			fpos[0] = position.X;
			fpos[1] = position.Y;
			fpos[2] = position.Z;
			setFloatVec("light_position", fpos, 3);

			SColorf color = light2->getLightData().DiffuseColor;
			fpos[0] = color.r;
			fpos[1] = color.g;
			fpos[2] = color.b;
			setFloatVec("light_diffuse", fpos, 3);

			setFloat("light_r", light2->getLightData().Radius);
		}

		float fpos[3];
		vector3df position = cam->getPosition();
		fpos[0] = position.X;
		fpos[1] = position.Y;
		fpos[2] = position.Z;
		setFloatVec("CAMERA_POSITION", fpos, 3);

		setInt("pass", pass);
	}

	void EndPass()
	{
	}

};
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

I see what you are doing but would you have to render the object several times?

I implemented an infinte lights shader by passing large arrays and using loops in the shader code to process infinite amounts of lights in a single rendering of the object.

well they arent infinite lights but the code is extensible and uses "fake dynamic memory mangement" to render a user defined amount of lights

Since currently shaders dont have dynamic memory management the user specifies the maxiumum amount of lights they think their card can handle and the shader code is modified in runtime before its compiled

therefore multiple "passes" or calculations can be achieved with no Hardwired code moreover the object is rendered once only

real use of multiple passes would require using the old image then using it again in ways that cannot be bypassed by loops, such as a grass/fur shader since the effect defies the size of the mesh (most algorithms render a sphere with dots each pass that gets bigger each pass then all the sphere are combined by a postprocessor)

good idea for multiple lights but i belive your method require the whole object to be rendered again ie to get the vertices down from the cpu->agp->gpu

rather than computing lights info in a array passed to a shader with only 1
cpu->agp->gpu

Btw i didnt see your shader code but i guess thats what you are doing if i have misunderstood your method then please accept my apologies
chromdragon
Posts: 101
Joined: Wed Feb 15, 2006 4:22 pm
Location: RO

Post by chromdragon »

yes that's right!

count = Begin() return the number of passes on begin rendering af a node

for every pass I re-render the node with BeginPass(), EndPass()

End()

This method is dynamic and the loops are in the C++ code not in the Shader code. And every pass is blended with additive blending.
(I chose this method because loops must be fully unwrap in Shader Model 2.0)

Tks for the comment! 8)

Code: Select all

		// draw everything

		glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(video::SColor), &ColorBuffer[0]);
		glNormalPointer(GL_FLOAT, sizeof(S3DVertex), &vertices[0].Normal);
		glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &vertices[0].TCoords);
		glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex),  &vertices[0].Pos);

		for(s32 i=0; i<count; i++)
		{
			mat->BeginPass(i);

			if (i > 0)
			{
				glEnable(GL_BLEND);
				glBlendFunc(GL_ONE, GL_ONE);
			}
			
			glDrawElements(GL_TRIANGLES, triangleCount * 3, GL_UNSIGNED_SHORT, indexList);

			mat->EndPass();

			if (i > 0)
				glDisable(GL_BLEND);

			glFlush();
		}

		glDisableClientState(GL_COLOR_ARRAY);
		glDisableClientState(GL_VERTEX_ARRAY);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY );
		glDisableClientState(GL_NORMAL_ARRAY );
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Thanks for clearing things up.

Nice method of yours is that it doesnt require high shader models
I dont see your method as very useful for lighting but the glblend method eliminates the need for a postprocessor when rendering grass.

Thats pretty nice way of rendering grass!

I hope you devlop this method into something cool that takes advantages of its unique approach.
chromdragon
Posts: 101
Joined: Wed Feb 15, 2006 4:22 pm
Location: RO

Post by chromdragon »

Yup! hope to make some nice stuff soon.
Xaron
Posts: 310
Joined: Sun Oct 16, 2005 7:39 am
Location: Germany
Contact:

Post by Xaron »

omaremad wrote:I implemented an infinte lights shader by passing large arrays and using loops in the shader code to process infinite amounts of lights in a single rendering of the object.
Hi,

could you please give me an example how to do multiple lights using shaders in one pass?

Thanks and best regards - Xaron
Post Reply