[C++] Postprocessing class and shaders (GLSL and HLSL)

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

here's the one i have...

Image

Image
Image
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Yeah, it works fine with DX9 for me on my ATI card. So for some reason I think it has to do with the sampler mapping in the GLSL shaders. Anyways here are the screenshots, and one screenshot showing an emboss-like effect I got by fooling around with the GLSL shader:

DX9:
Image

OpenGL:
Image

Emboss:
Image
TheQuestion = 2B || !2B
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

uniform vec4 vecValues[2];
Heres you're problem, ATI (Well especially the 200M which Halifax has) don't support uniform arrays in GLSL (Only HLSL), atleast under Irrlicht atm. Infact it used to not work on any card, but we fixed it by acquiring the right uniform location, unfortunately ATI cards still refuse to accept them. So whats happening here is "vecValues[0].x" is evaluating to 0 (Because the 200M can't find the uniform variable since its in an array), and no bloom gets added!

I recommend just using alternate names like "vecValues1" and "vecValues2". (Since it's just 2 values anyway, the real problem comes down hard when you are doing hardware skinning with an array of 50 constants)

Btw nice work on fixing up that shader Halifax, you're learning how to treat your fussy ATI glsl compiler right. :P

Cheers and good luck :D
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Haha, thanks. I just can't wait until I get my nVidia card. By the way, what are the 50 values you would need for hardware skinning? (I have never looked into skinning, so I don't know what is involved.)
TheQuestion = 2B || !2B
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Well 50 is just an appropriate value, it can be any amount you want (But the shader specs limiting the amount of constant variables would restrict you to around 60), the values themselves are transformation matrices for all the different bones in the mesh. The vertex does a lookup from this array using an index stored in a vertex attribute (Could just be the red component of the vertex color or something), and uses that matrix to contribute to its world transform. This is also the technique I use for instancing, except instead of moving different bones in one mesh you would move different meshes that have been packed into a single meshbuffer.

You might find it amusing that the SkinnedMesh class offers an option "setHardwareSkinning", although this function doesn't perform hardware skinning, its actually queit useful because what it does is disable software skinning, but still updates the individual bone transformation matrices of the mesh (But not the vertices), so the mesh itself remains static, and allows you to apply you're own custom hardware skinning shader. I think that we should add a "appointBoneIndexToVertexColor" function so that bone ids are appointed for you automatically.

Ok gone waaay offtopic there. :roll:

Cheers
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Haha, oh well, it is always fun to read you talk about shaders and all the such. I tried implementing a replacement for arrays and it doesn't seem to be working, I don't know why. I am posting the code, and the errors for the HLSL in D3D9.

By the way I improved the blur shaders so that they use less instruction during the loop, and use lookup tables as well, but anyways, here is the code.

Pay close attention to the additions to the shader constant setting functions. They seem alright and viable to me, nothing new. I even left the previous code and just commented it out so it could be compared.

Errors
'firstScreen' Registers:[begin:1, count:1]
'vecValue0' Registers:[begin:0, count:1]
HLSL Variable to set not found: 'vecValue2'. Available variables are:
'colorMap' Registers:[begin:0, count:1]
'firstScreen' Registers:[begin:1, count:1]
'vecValue0' Registers:[begin:0, count:1]
HLSL Variable to set not found: 'vecValue3'. Available variables are:
'colorMap' Registers:[begin:0, count:1]
'firstScreen' Registers:[begin:1, count:1]
'vecValue0' Registers:[begin:0, count:1]
Main.cpp

Code: Select all

#include "PostProcessing.h"
#include <Irrlicht.h>

#pragma comment(lib, "Irrlicht.lib")
 
int main(int argc, char **argv)
{
	IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9);
	video::IVideoDriver *driver = device->getVideoDriver();
	scene::ISceneManager *smgr = device->getSceneManager();
	gui::IGUIEnvironment *guienv = device->getGUIEnvironment();
	device->getFileSystem()->addZipFileArchive("map-20kdm2.pk3");
	smgr->addOctTreeSceneNode(smgr->getMesh("20kdm2.bsp"));
	smgr->addCameraSceneNodeFPS();

	//invert colors
//	PostProcessing *PP_Test = new PostProcessing(smgr,"Shaders/PP_GL_Invert.fx","Shaders/PP_DX_Invert.fx",video::EPST_PS_1_4,512,256);

	//build up the effect chain for bloom
	PostProcessing *PP_Test = new PostProcessing(smgr,"Shaders/PP_GL_Bloom1.fx","Shaders/PP_DX_Bloom1.fx",video::EPST_PS_3_0,512,256);
    PP_Test->setShaderParameters(0.5f);
    PostProcessing *Test2 = PP_Test->addMaterial("Shaders/PP_GL_Bloom2.fx","Shaders/PP_DX_Bloom2.fx",video::EPST_PS_3_0,128,128);
    Test2->setShaderParameters(0.01f);
    Test2 = Test2->addMaterial("Shaders/PP_GL_Bloom3.fx","Shaders/PP_DX_Bloom3.fx",video::EPST_PS_3_0,128,128);
    Test2->setShaderParameters(0.01f);
    Test2 = Test2->addMaterial("Shaders/PP_GL_Bloom4.fx","Shaders/PP_DX_Bloom4.fx",video::EPST_PS_3_0,512,256);
    Test2->setShaderParameters(0.7f);
    Test2->setSecondMap(PP_Test->getFirstMap(),video::ETC_CLAMP);

	//the main loop
	while(device->run())
	{
		 if (device->isWindowActive())
		 {
			driver->beginScene(true, true, video::SColor(255,150,180,255));
			
			//render the scene into the postprocessing texture
			driver->setRenderTarget(PP_Test->getFirstMap(), true, true, video::SColor(255,150,180,255));
			smgr->drawAll();
			driver->setRenderTarget(0);
			
			//render the effect chain
			PP_Test->renderEffect();
			
			guienv->drawAll();
			driver->endScene();
		  }
	}
	
	device->drop();
}
PostProcessing.h

Code: Select all

/*
Copyright (c) 2008 Nils Daumann
 
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
 
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _POSTPROCESSING_H_
#define _POSTPROCESSING_H_
 
#include <irrlicht.h>
using namespace irr;
 
class PostProcessing_SetShaderConstants : public video::IShaderConstantSetCallBack
{
	public:
		PostProcessing_SetShaderConstants();
		
		virtual void OnSetConstants(video::IMaterialRendererServices *services,
		                            s32 userdata);
		//void setShaderParameters(f32 *paras){shaderparameters = paras;}
		void setShaderParameter(u32 index, f32 param);
 
	private:
		f32 sp[8];
};
 
/**
 * \brief Class which manages postprocessing effects
 *
 * To apply the effect, run
 * \code
 * driver->setRenderTarget(postprocessing->getFirstMap(), true, true, video::SColor(255,150,180,255));
 * \endcode
 * or similar before you render anything and run
 * \code
 * driver->setRenderTarget(0);
 * postprocessing->renderEffect();
 * \endcode
 * to actually run the shaders and render the result to the screen.
 */
class PostProcessing
{
	public:
		/**
		 * \brief Constructor
		 * \param smgr Scene manager which is used for the post progressing
		 * \param filename_gl Path to the GLSL script
		 * \param filename_dx Path to the HLSL script
		 * \param type_ps Type of the pixel shader
		 * \param res_x Horizontal resolution of the used texture
		 * \param res_y Vertical resolution of the used texture
		 */
		PostProcessing(scene::ISceneManager *smgr,
		               const c8 *filename_gl,
		               const c8 *filename_dx,
		               video::E_PIXEL_SHADER_TYPE type_ps,
		               s32 res_x,
		               s32 res_y);
 
		/**
		 * \brief Destructor
		 */
		~PostProcessing();
 
		/**
		 * \brief Adds another stage and inserts it after this stage
		 * \param filename_gl Path to the GLSL script
		 * \param filename_dx Path to the HLSL script
		 * \param type_ps Type of the pixel shader
		 * \param res_x Horizontal resolution of the used texture
		 * \param res_y Vertical resolution of the used texture
		 */
		PostProcessing *addMaterial(const c8 *filename_gl,
		                            const c8 *filename_dx,
		                            video::E_PIXEL_SHADER_TYPE type_ps,
		                            s32 res_x,
		                            s32 res_y);
 
		/**
		 * \brief Renders this postprocessing chain
		 */
		void renderEffect();
 
		/**
		 * \brief Sets the second texture
		 */
		void setSecondMap(video::ITexture *tex, video::E_TEXTURE_CLAMP mode)
		{
			secondmap = tex;
			material.setTexture(1,secondmap);
			material.TextureLayer[1].TextureWrap = mode;
		}
 
		/**
		 * \brief Sets the parameters of the shader
		 */
		void setShaderParameters(f32 para1 = 0, f32 para2 = 0, f32 para3 = 0, f32 para4 = 0,
			f32 para5 = 0, f32 para6 = 0, f32 para7 = 0, f32 para8 = 0)
		{
			shaderparameters[0] = para1;
			shaderparameters[1] = para2;
			shaderparameters[2] = para3;
			shaderparameters[3] = para4;
			shaderparameters[4] = para5;
			shaderparameters[5] = para6;
			shaderparameters[6] = para7;
			shaderparameters[7] = para8;
		}
 
		/**
		 * \brief Returns a pointer to the material
		 */
		video::SMaterial *getMaterial(){return(&material);}
 
		/**
		 * \brief Returns a pointer to the first texture
		 */
		video::ITexture *getFirstMap(){return(firstmap);}
		/**
		 * \brief Returns a pointer to the second texture
		 */
		video::ITexture *getSecondMap(){return(secondmap);}
 
 
	private:
		PostProcessing_SetShaderConstants shadercallback;
 
		scene::ISceneManager *scenemgr;
		video::IVideoDriver *driver;
		video::S3DVertex vertices[4];
		video::SMaterial material;
		s32 matid;
		f32 shaderparameters[8];
		PostProcessing *prevstage;
		PostProcessing *nextstage;
 
		video::ITexture *firstmap;
		video::ITexture *secondmap;
};
 
#endif
PostProcessing.cpp

Code: Select all

/*
Copyright (c) 2008 Nils Daumann
 
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
 
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
 
#include "PostProcessing.h"

PostProcessing_SetShaderConstants::PostProcessing_SetShaderConstants()
{
	for (u32 i = 0; i < 8; i ++)
		sp[i] = 0.0f;
}
 
void PostProcessing_SetShaderConstants::OnSetConstants(video::IMaterialRendererServices *services, s32 userdata)
{
	// set the materialparameters
	//services->setPixelShaderConstant("vecValues",shaderparameters, 8);
	services->setPixelShaderConstant("vecValue0", &sp[0], 1);
	services->setPixelShaderConstant("vecValue1", &sp[1], 1);
	services->setPixelShaderConstant("vecValue2", &sp[2], 1);
	services->setPixelShaderConstant("vecValue3", &sp[3], 1);
	services->setPixelShaderConstant("vecValue4", &sp[4], 1);
	services->setPixelShaderConstant("vecValue5", &sp[5], 1);
	services->setPixelShaderConstant("vecValue6", &sp[6], 1);
	services->setPixelShaderConstant("vecValue7", &sp[7], 1);
	
	if(userdata == 1)
	{
		//set Textures for openGL Shaders
		int texture1 = 0;
		services->setPixelShaderConstant("texture1",(float*)&texture1, 1);
		int texture2 = 1;
		services->setPixelShaderConstant("texture2",(float*)&texture2, 1);
	}
}

void PostProcessing_SetShaderConstants::setShaderParameter(u32 index, f32 param)
{
	if (index > 7)
		return;
	
	sp[index] = param;
}
 
PostProcessing::PostProcessing(scene::ISceneManager *smgr, const c8 *filename_gl,
	const c8 *filename_dx, video::E_PIXEL_SHADER_TYPE type_ps, s32 res_x, s32 res_y)
{
	driver = smgr->getVideoDriver();
 
	if(driver->getDriverType() == video::EDT_OPENGL || driver->getDriverType() == video::EDT_DIRECT3D9)
	{
		vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
		vertices[1] = video::S3DVertex(-1.0f,  1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
		vertices[2] = video::S3DVertex( 1.0f,  1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
		vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
		
		video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
		scenemgr = smgr;
 
		prevstage = NULL;
		nextstage = NULL;
 
		setShaderParameters();
		//shadercallback.setShaderParameters(&shaderparameters[0]);
		shadercallback.setShaderParameter(0, shaderparameters[0]);
		shadercallback.setShaderParameter(1, shaderparameters[1]);
		shadercallback.setShaderParameter(2, shaderparameters[2]);
		shadercallback.setShaderParameter(3, shaderparameters[3]);
		shadercallback.setShaderParameter(4, shaderparameters[4]);
		shadercallback.setShaderParameter(5, shaderparameters[5]);
		shadercallback.setShaderParameter(6, shaderparameters[6]);
		shadercallback.setShaderParameter(7, shaderparameters[7]);
 
		if(driver->getDriverType() == video::EDT_OPENGL)
		{
			matid = gpu->addHighLevelShaderMaterialFromFiles
			(
				"PP_GL_Vertex.fx",
				"main",
				video::EVST_VS_1_1,
				filename_gl,
				"main",
				type_ps,
				&shadercallback,
				video::EMT_SOLID,
				1
			);
		}else
		{
			matid = gpu->addHighLevelShaderMaterialFromFiles
			(
				"PP_DX_Vertex.fx",
				"main",
				video::EVST_VS_1_1,
				filename_dx,
				"main",
				type_ps,
				&shadercallback,
				video::EMT_SOLID,
				0
			);
		}
 
		firstmap = driver->createRenderTargetTexture(core::dimension2d<s32>(res_x,res_y));
		secondmap = NULL;
		material.Wireframe = false;
		material.Lighting = false;
		material.setTexture(0,firstmap);
		material.TextureLayer[0].TextureWrap = video::ETC_CLAMP;
		material.MaterialType = (video::E_MATERIAL_TYPE)matid;
	}
}
 
PostProcessing::~PostProcessing()
{
	if(nextstage != NULL)
	{
		delete nextstage;
	}
}
 
PostProcessing *PostProcessing::addMaterial(const c8 *filename_gl, const c8 *filename_dx,
	video::E_PIXEL_SHADER_TYPE type_ps, s32 res_x, s32 res_y)
{
	nextstage = new PostProcessing(scenemgr,filename_gl,filename_dx,type_ps,res_x,res_y);
 
	return nextstage;
}
 
void PostProcessing::renderEffect()
{
	u16 indices[] = {0,1,2,0,2,3};
	driver->setMaterial(material);
 
	if(nextstage != NULL)
	{
		driver->setRenderTarget(nextstage->getFirstMap(), true, true, video::SColor(255,150,180,255));
		driver->drawIndexedTriangleList(vertices, 6, indices, 2);
		driver->setRenderTarget(0);
 
		nextstage->renderEffect();
	}else
	{
		driver->drawIndexedTriangleList(vertices, 6, indices, 2);
	}
}
PP_DX_Bloom1

Code: Select all

/***********************************************************************
Copyright (c) 2008 Nils Daumann
 
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
 
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*************************************************************************/

/************************************************************************
HLSL Bloom
Effect 1: Filtering out dark Colors, needs PS 1.4
*************************************************************************/

//float4 vecValues[2];
sampler2D colorMap : register(s0);
float vecValue0, vecValue1, vecValue2, vecValue3, vecValue4, vecValue5, vecValue6, vecValue7;


float4 main( float2 Tex:TEXCOORD0 ) : COLOR0 
{
	float4 Color = tex2D(colorMap, Tex.xy);

	if(dot(Color.rgb, float3(0.299f, 0.587f, 0.114f)) < vecValue0)
	{
		Color.rgb = 0;
	}

	return Color;
}
PP_DX_Bloom2

Code: Select all

/***********************************************************************
Copyright (c) 2008 Nils Daumann
 
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
 
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*************************************************************************/

/************************************************************************
HLSL Bloom
Effect 2: Horizontal blur, needs PS 2.0
*************************************************************************/


//float4 vecValues[2];
static int blurRadius = 5;
sampler2D colorMap : register(s0);
float vecValue0, vecValue1, vecValue2, vecValue3, vecValue4, vecValue5, vecValue6, vecValue7;

float4 main(float2 Tex:TEXCOORD0):COLOR0
{
	float2 pos[11];
	pos[0]  = float2(-5.0,0.0);
	pos[1]  = float2(-4.0,0.0);
	pos[2]  = float2(-3.0,0.0);
	pos[3]  = float2(-2.0,0.0);
	pos[4]  = float2(-1.0,0.0);
	pos[5]  = float2(0.0,0.0);
	pos[6]  = float2(1.0,0.0);
	pos[7]  = float2(2.0,0.0);
	pos[8]  = float2(3.0,0.0);
	pos[9]  = float2(4.0,0.0);
	pos[10] = float2(5.0,0.0);

	float samples[11];
	samples[0]  = 0.01222447;
	samples[1]  = 0.02783468;
	samples[2]  = 0.06559061;
	samples[3]  = 0.12097757;
	samples[4]  = 0.17466632;
	samples[5]  = 0.19741265;
	samples[6]  = 0.17466632;
	samples[7]  = 0.12097757;
	samples[8]  = 0.06559061;
	samples[9]  = 0.02783468;
	samples[10] = 0.01222447;

	float4 Color = float4(0.0,0.0,0.0,0.0);
	float2 tempTex = Tex;
	int i;

	for (i = 0; i < 11; i ++)
	{
		Color += tex2D(colorMap, tempTex + (pos[i] * vecValue0)) * samples[i];
	}

	return Color;

	//float4 Color = tex2D(colorMap,Tex.xy);
	//float2 tempTex;
	//tempTex.y = Tex.y;
	//for(int i=-blurRadius;i<=blurRadius;i++)
	//{
	//	tempTex.x = Tex.x+i*vecValues[0].x;
	//	Color += tex2D(colorMap,tempTex.xy);
	//}
	
	//return Color/(blurRadius*2+1);
}
PP_DX_Bloom3

Code: Select all

/***********************************************************************
Copyright (c) 2008 Nils Daumann
 
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
 
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*************************************************************************/

/************************************************************************
HLSL Bloom
Effect 3: Vertical blur, needs PS 2.0
*************************************************************************/


//float4 vecValues[2];
static int blurRadius = 5;//number of px
sampler2D colorMap : register(s0);
float vecValue0, vecValue1, vecValue2, vecValue3, vecValue4, vecValue5, vecValue6, vecValue7;

float4 main(float2 Tex:TEXCOORD0):COLOR0
{	
	float2 pos[11];
	pos[0]  = float2(0.0,-5.0);
	pos[1]  = float2(0.0,-4.0);
	pos[2]  = float2(0.0,-3.0);
	pos[3]  = float2(0.0,-2.0);
	pos[4]  = float2(0.0,-1.0);
	pos[5]  = float2(0.0,0.0);
	pos[6]  = float2(0.0,1.0);
	pos[7]  = float2(0.0,2.0);
	pos[8]  = float2(0.0,3.0);
	pos[9]  = float2(0.0,4.0);
	pos[10] = float2(0.0,5.0);

	float samples[11];
	samples[0]  = 0.01222447;
	samples[1]  = 0.02783468;
	samples[2]  = 0.06559061;
	samples[3]  = 0.12097757;
	samples[4]  = 0.17466632;
	samples[5]  = 0.19741265;
	samples[6]  = 0.17466632;
	samples[7]  = 0.12097757;
	samples[8]  = 0.06559061;
	samples[9]  = 0.02783468;
	samples[10] = 0.01222447;

	float4 Color = float4(0.0,0.0,0.0,0.0);
	float2 tempTex = Tex;
	int i;

	for (i = 0; i < 11; i ++)
	{
		Color += tex2D(colorMap, tempTex + (pos[i] * vecValue0)) * samples[i];
	}

	return Color;

//	float4 Color = tex2D(colorMap,Tex.xy);
//	float2 tempTex;
//	tempTex.x = Tex.x;
//	for(int i=-blurRadius;i<=blurRadius;i++)
//	{
//		tempTex.y = Tex.y+i*vecValues[0].x;
//		Color += tex2D(colorMap,tempTex.xy);
//	}
//	return Color/(blurRadius*2+1);
}
PP_DX_Bloom4

Code: Select all

/***********************************************************************
Copyright (c) 2008 Nils Daumann
 
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
 
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*************************************************************************/

/************************************************************************
GLSL Bloom
Effect 4: Add the blurred image to the original one, needs PS 2.0
*************************************************************************/


//float4 vecValues[2];
sampler2D colorMap : register(s0);
sampler2D firstScreen : register(s1);
float vecValue0, vecValue1, vecValue2, vecValue3, vecValue4, vecValue5, vecValue6, vecValue7;

float4 main(float2 Tex: TEXCOORD0):COLOR0
{
	float4 Color = tex2D(firstScreen,Tex.xy);
	Color += vecValue0*tex2D(colorMap,Tex);
	return Color;
}
By the way, working with this is making me want to get back to writing my shader stuff. :lol:
Last edited by Halifax on Tue Jun 03, 2008 12:12 pm, edited 1 time in total.
TheQuestion = 2B || !2B
Slin
Posts: 23
Joined: Sat May 17, 2008 9:31 am
Location: Eutin, Germany
Contact:

Post by Slin »

Thanks for your explanation BlindSide :)
Halifax, I sometimes get those errors as well and I have no idea why...
But also look at your code again, even if it would work, the values would all be 0. You don´t assign another value to sp.
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Slin wrote:Thanks for your explanation BlindSide :)
Halifax, I sometimes get those errors as well and I have no idea why...
But also look at your code again, even if it would work, the values would all be 0. You don´t assign another value to sp.
No that is just in the constructor of the shader constant callback. But in the PostProcessing construtor it sets the values to whatever the values are from the shaderparameters array.

I also changed it to set it again whenever the setShaderParameters() function is called. (Not evident above.)

But even if they were 0, that should not affect whether the variables are available in the shader.
TheQuestion = 2B || !2B
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

not sure if this is possible with the code shown above, assign a shader to a material on-the-fly.

let's say we have a list of shaders (phong, blinn, lambert, anisotropic, etc) shown on a list. i could pull-down a menu and select from them, then assign it to a material. then i can set the attributes of selected shader, for example a blinn shader, inside an attribute editor.

in the attribute editor, i can have the option of setting-up the bump map or even the displacement map.

normally, with blinn shader selected, i can tweak ambient, specular and rgba values as well.

with that code, i think it is now possible to have those cool features.
Image
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Well you could definitely write up some code to do that, but no I don't think the code above would handle that. Just for the simple fact that this code is meant for a post-processing framework which means that it only handles shaders that operate on the 2D images produced and nothing else.
TheQuestion = 2B || !2B
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

First of all, that advice was meant for GLSL not HLSL, so I have no idea why you are doing this in HLSL even though HLSL worked fine anyway.

Second of all, those are not errors but malignant warnings, they will not affect the operation of the shader in anyway. They are simply telling you that there is an unused uniform variable in your shader that you are assigning, kinda like when you have an unused variable in C++, its not really gonna harm anything. That said, the constant printing of those errors tends to affect performance a bit, so its best to not set constants that you are not using (In this case you are only using vecValue0, so don't set the rest.

By the way, I'm extremely confused here, why is an HLSL file labeled with GLSL bloom? You can't do that, just because the lenient NVidia compiler parses it as CG code doesn't mean you can freely use HLSL methods in GLSL, because it will only work on NVidia cards (And you never know when they will fix this wrong behaviour). If you don't get what I'm talking about, have a look at the GLSL specifications, you will see that those functions and keywords you are using are nowhere to be seen.

Cheers
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Slin
Posts: 23
Joined: Sat May 17, 2008 9:31 am
Location: Eutin, Germany
Contact:

Post by Slin »

It works nice if the PostProcessing.cpp looks like this (it does only effect something when using OpenGL):

Code: Select all

/*
Copyright (c) 2008 Nils Daumann
 
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
 
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
 
#include "PostProcessing.h"
 
void PostProcessing_SetShaderConstants::OnSetConstants(video::IMaterialRendererServices *services, s32 userdata)
{
	if(userdata == 0)
	{
		// set the materialparameters
		services->setPixelShaderConstant("vecValues",shaderparameters, 8);
	}else
	{
		int i;
		c8 *constname;
		
		// set the materialparameters
		for(i = 0; i < 8; i++)
		{
			constname = new char[strlen("Value") + (int)log(i+1) + 2];
			snprintf(constname, strlen("Value") + (int)log(i+1) + 2, "%s%d", "Value", i);

			services->setPixelShaderConstant((const c8*)constname,&shaderparameters[i], 1);
			
			delete[] constname;
		}
	 	 
		//set Textures for openGL Shaders
		int texture = 0;
		services->setPixelShaderConstant("Texture0",(float*)&texture, 1);
		texture += 1;
		services->setPixelShaderConstant("Texture1",(float*)&texture, 1);
	}
}
 
PostProcessing::PostProcessing(scene::ISceneManager *smgr, const c8 *filename_gl,
	const c8 *filename_dx, video::E_PIXEL_SHADER_TYPE type_ps, s32 res_x, s32 res_y, PostProcessing *previous)
{
	driver = smgr->getVideoDriver();
 
	if(driver->getDriverType() == video::EDT_OPENGL || driver->getDriverType() == video::EDT_DIRECT3D9)
	{
		vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
		vertices[1] = video::S3DVertex(-1.0f,  1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
		vertices[2] = video::S3DVertex( 1.0f,  1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
		vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
		
		video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
		scenemgr = smgr;
 
		prevstage = previous;
		nextstage = NULL;
 
		setShaderParameters();
		shadercallback.setShaderParameters(&shaderparameters[0]);
 
		if(driver->getDriverType() == video::EDT_OPENGL)
		{
			matid = gpu->addHighLevelShaderMaterialFromFiles
			(
				"PP_GL_Vertex.fx",
				"main",
				video::EVST_VS_1_1,
				filename_gl,
				"main",
				type_ps,
				&shadercallback,
				video::EMT_SOLID,
				1
			);
		}else
		{
			matid = gpu->addHighLevelShaderMaterialFromFiles
			(
				"PP_DX_Vertex.fx",
				"main",
				video::EVST_VS_1_1,
				filename_dx,
				"main",
				type_ps,
				&shadercallback,
				video::EMT_SOLID,
				0
			);
		}
 
		firstmap = driver->createRenderTargetTexture(core::dimension2d<s32>(res_x,res_y));
		secondmap = NULL;
		material.Wireframe = false;
		material.Lighting = false;
		material.setTexture(0,firstmap);
		material.TextureLayer[0].TextureWrap = video::ETC_CLAMP;
		material.MaterialType = (video::E_MATERIAL_TYPE)matid;
	}
}
 
PostProcessing::~PostProcessing()
{
	if(nextstage != NULL)
	{
		delete nextstage;
	}
}
 
PostProcessing *PostProcessing::addMaterial(const c8 *filename_gl, const c8 *filename_dx,
	video::E_PIXEL_SHADER_TYPE type_ps, s32 res_x, s32 res_y)
{
	nextstage = new PostProcessing(scenemgr,filename_gl,filename_dx,type_ps,res_x,res_y,this);
 
	return nextstage;
}
 
void PostProcessing::renderEffect()
{
	u16 indices[] = {0,1,2,0,2,3};
	driver->setMaterial(material);
 
	if(nextstage != NULL)
	{
		driver->setRenderTarget(nextstage->getFirstMap(), true, true, video::SColor(255,150,180,255));
		driver->drawIndexedTriangleList(vertices, 6, indices, 2);
		driver->setRenderTarget(0);
 
		nextstage->renderEffect();
	}else
	{
		driver->drawIndexedTriangleList(vertices, 6, indices, 2);
	}
}

You will have to rename texture1 and texture2 in the GLSL shader to Texture0 and Texture1. The values are passed to the shader as Value0...Value7.

Edit: You also have to include stdlib.h.
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

BlindSide wrote:First of all, that advice was meant for GLSL not HLSL, so I have no idea why you are doing this in HLSL even though HLSL worked fine anyway.
Yeah I was just trying it out because working with the GLSL version wasn't an option last night. Something was really messed up, and I am guessing it was with my drivers or something, but a restart fixed it. But for some reason when I compiled with OpenGL the program ran at about 1 FPS and took a crap load of time to start up, but with Direct3D9 it ran at about 80 FPS and starting up fast so that I could debug easier. At the least, I was just messing around.
BlindSide wrote: By the way, I'm extremely confused here, why is an HLSL file labeled with GLSL ...
Was that directed at me?
Slin wrote: It works nice if the PostProcessing.cpp looks like this (it does only effect something when using OpenGL):
I don't quite understand why you are using all that for setting the values. Do you plan on extending pass 8 user data variables in the shaders? If not, then I don't see why you can't just set it explicity, or use the internal Irrlicht strings.

EDIT:

Well I got OpenGL working, and it was a very good learning experience, BlindSide, thanks.
TheQuestion = 2B || !2B
m68135
Posts: 1
Joined: Fri Oct 31, 2008 10:24 pm

Post by m68135 »

Only the invert worked fine for me.

When I tried bloom (any of them), what happens is that non-textured surfaces become completely black. Textured surfaces stay completely bright. And no glow effect whatsoever.

I'm using the openscenegraph engine (OpenGL, GLSL). Any ideas?

Image: http://magiadosdoces.com/temp/car.jpg

Other cars are bluish because they have an environment map. Notice that my car, the semaphores, and some other things are black.
Halan
Posts: 447
Joined: Tue Oct 04, 2005 8:17 pm
Location: Germany, Freak City
Contact:

Post by Halan »

i didn't try this framework yet but it looks pretty clean :)

Maybe one that could go into the core of irrlicht?

greets,
Halan
Post Reply