Terrain Shader Porblem...

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!
Post Reply
Revan1985
Posts: 89
Joined: Tue May 08, 2007 4:11 pm
Location: Italy

Terrain Shader Porblem...

Post by Revan1985 »

EDIT:
OK, i've found the problem...
i need to change the Texture from 0 to 1, in the m_pTerrain->setMaterialTexture()...
but the problem now is that i see the terrain completely black...
now i'll try again to solve it...
if you have idea, post them ^^'

ORIGINAL:

I'm using this shader in my terrain program...

PS

Code: Select all

float xAmbient;

Texture xTexture0;

sampler TextureSampler0 = sampler_state
{
	texture = <xTexture0>;
	magfilter = LINEAR;
	minfilter = LINEAR;
	mipfilter = LINEAR;
	AddressU = wrap;
	AddressV = wrap;
};

struct MTVertexToPixel
{
	float4	Position			: POSITION;
	float4	Color				: COLOR0;
	float	LightingFactor		: TEXCOORD0;
	float2 TextureCoords		: TEXCOORD1;
	/*float4 LightDirection		: TEXCOORD2;*/
	/*float4 TextureWeights		: TEXCOORD3;*/
};

struct MTPixelToFrame
{
	float4 Color : COLOR0;
};

MTPixelToFrame TexturedPS(MTVertexToPixel PSin)
{
	MTPixelToFrame Output = (MTPixelToFrame)0;
		
	Output.Color = tex2D(TextureSampler0, PSin.TextureCoords);
	Output.Color.rgb *= saturate(PSin.LightingFactor + xAmbient);
	
	return Output;
}
VS

Code: Select all

float4x4 xView;
float4x4 xProjection;
float4x4 xWorld;

bool xEnableLighting;
float3 xLightDirection;

struct MTVertexToPixel
{
	float4	Position			: POSITION;
	float4	Color				: COLOR0;
	float	LightingFactor		: TEXCOORD0;
	float2	TextureCoords		: TEXCOORD1;
};

MTVertexToPixel TexturedVS( float4 inPos : POSITION, float3 inNormal : NORMAL,
	float2 inTexCoords : TEXCOORD0)
{
	MTVertexToPixel Output = (MTVertexToPixel)0;
	float4x4 preViewProjection = mul(xView, xProjection);
	float4x4 preWorldViewProjection = mul(xWorld, preViewProjection);
	
	Output.Position = mul(inPos, preWorldViewProjection);
	Output.TextureCoords = inTexCoords;
	
	float3 Normal = normalize(mul(normalize(inNormal), xWorld));
	Output.LightingFactor = 1;
	if(xEnableLighting)
	Output.LightingFactor = saturate(dot(Normal, -xLightDirection));
	
	return Output;
}
and i'm using this code in my program...

CTerrain.h

Code: Select all

#ifndef __CTERRAIN_H__
#define __CTERRAIN_H__

#include "stdafx.h"

class CTerrain : public scene::ISceneNode, video::IShaderConstantSetCallBack
{
public:
	CTerrain(scene::ISceneManager* smgr, u32 dimension = 512, f32 maxHeight = 92,
		const core::vector3df& position = core::vector3df(0.0f, 0.0f, 0.0f),
		const core::vector3df& rotation = core::vector3df(0.0f, 0.0f, 0.0f),
		const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f),
		scene::ISceneNode* parent = 0, s32 id = -1);
	
	~CTerrain();
	void GenerateCasual();
	void GenerateTexture();
	
	virtual void OnRegisterSceneNode();
	virtual void OnAnimate(u32 timeMs);

	virtual void render();

	virtual const core::aabbox3d<f32>& getBoundingBox() const { return m_pTerrain->getBoundingBox(); }

	virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData);


	core::vector3df getTerrainCenter(){ return core::vector3df(m_pTerrain->getTerrainCenter()); }
	core::vector3df getTerrainPosition(){ return m_pTerrain->getPosition(); }
	core::vector3df getTerrainScale(){ return m_pTerrain->getScale(); }

	core::dimension2d<s32> getTerrainDimension(){ return core::dimension2d<s32>(m_iDimension, m_iDimension); }
	u32 getDimension(){ return m_iDimension; }

private:
	u32													m_iDimension;

	f32													m_fMaxHeight;
	f32													m_fAmbient;

	scene::ITerrainSceneNode*		m_pTerrain;
	
	scene::ISceneManager*				m_pSmgr;
	video::IVideoDriver*				m_pDriver;

	ITimer*											m_pTimer;
	
	video::IImage*							m_pImage;

	video::ITexture*						m_pGrass;
	video::ITexture*						m_pRock;
	video::ITexture*						m_pSand;
	video::ITexture*						m_pSnow;

	s32													m_sShaderMaterial;

	scene::ICameraSceneNode*		m_pCamera;

	void Colorate();
};

#endif
CTerrain.cpp

Code: Select all

#include "stdafx.h"
#include "CTerrain.h"

CTerrain::CTerrain(scene::ISceneManager* smgr, u32 dimension, f32 maxHeight, const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale,
									 scene::ISceneNode* parent, s32 id) :
scene::ISceneNode(parent ? parent : smgr->getRootSceneNode(), smgr, id, position, rotation, scale)
{
	m_fMaxHeight = maxHeight;
	m_iDimension = dimension;
	m_pSmgr = smgr;
	m_fAmbient = 0.9f;
	m_pDriver = m_pSmgr->getVideoDriver();
	m_pImage = m_pDriver->createImage(video::ECF_A8R8G8B8, core::dimension2d<s32>(m_iDimension, m_iDimension));

	GenerateCasual();

	m_pDriver->writeImageToFile(m_pImage, "./terrain/data/heigthmap.bmp");
	m_pImage->drop();

	m_pTerrain = m_pSmgr->addTerrainSceneNode("./terrain/data/heigthmap.bmp", 0, -1, core::vector3df(0.0f, 0.0f, 0.0f), core::vector3df(0.0f, 0.0f, 0.0f),
		core::vector3df(0.0f, 0.0f, 0.0f), video::SColor(255, 255, 255, 255), 5, scene::ETPS_17, 3);
	m_pTerrain->setScale(core::vector3df(10.0f, 5.0f, 10.0f));
	m_pTerrain->setPosition(core::vector3df(0.0f, 0.0f, 0.0f));

	m_pImage = m_pDriver->createImage(video::ECF_A8R8G8B8, core::dimension2d<s32>(m_iDimension, m_iDimension));

	GenerateTexture();

	m_pDriver->writeImageToFile(m_pImage, "./terrain/data/texture.bmp");
	m_pImage->drop();

	//m_pTerrain->setMaterialFlag(video::EMF_LIGHTING, false);
	//m_pTerrain->setMaterialTexture(0, m_pDriver->getTexture("./terrain/data/texture.bmp"));

	video::IGPUProgrammingServices* GPUProgrammingServices = m_pDriver->getGPUProgrammingServices();

	std::string TerrainPixelShader;
	std::string TerrainVertexShader;

	if (m_pDriver->getDriverType()==video::EDT_DIRECT3D9)
	{
		TerrainPixelShader="./terrain/shaders/Terrain_ps.hlsl";
		TerrainVertexShader="./terrain/shaders/Terrain_vs.hlsl";
	}
	else if (m_pDriver->getDriverType()==video::EDT_OPENGL)
	{
		TerrainPixelShader="./terrain/shaders/Terrain_ps.glsl";
		TerrainVertexShader="./terrain/shaders/Terrain_vs.glsl";
	}

	m_sShaderMaterial = GPUProgrammingServices->addHighLevelShaderMaterialFromFiles(
		TerrainVertexShader.c_str(),"TexturedVS",video::EVST_VS_2_0,
		TerrainPixelShader.c_str(),"TexturedPS",video::EPST_PS_1_1,
		this,video::EMT_LIGHTMAP);

	m_pGrass = m_pDriver->getTexture("./terrain/data/grass.bmp");
	m_pTerrain->setMaterialType((video::E_MATERIAL_TYPE)m_sShaderMaterial);
	m_pTerrain->setMaterialTexture(0, m_pGrass);
	
	scene::ICameraSceneNode* CurrentCamera =	m_pSmgr->getActiveCamera();
	m_pCamera = m_pSmgr->addCameraSceneNode();
	m_pCamera->setFarValue(CurrentCamera->getFarValue());
	m_pCamera->setFOV(CurrentCamera->getFOV());

	m_pSmgr->setActiveCamera(CurrentCamera);
	

}
/* */
CTerrain::~CTerrain()
{
	m_pCamera->drop();
}
/* */
void CTerrain::GenerateCasual()
{
	srand((unsigned)time(0));

	m_pImage->fill(video::SColor(255, 0, 0, 0));

	for(u32 counter = 0; counter < (m_iDimension / 16); ++counter)
	{
		u32 x = rand() % m_iDimension;
		u32 y = rand() % m_iDimension;

		for(int i = 0; i < 5000; ++i)
		{
			s32 v = rand() % 4;

			switch(v)
			{
			case 0:
				if(++x > (m_iDimension - 1)){ --x; }
				break;
			case 1:
				if(++y > (m_iDimension - 1)){ --y; }
				break;
			case 2:
				if(--x < 0){ ++x; }
				break;
			case 3:
				if(--y < 0){ ++y; }
				break;
			}

			video::SColor color = m_pImage->getPixel(x, y);

			u32 red = color.getRed();
			u32 blue = color.getBlue();
			u32 green = color.getGreen();

			if((red += 16) > m_fMaxHeight){ red -= 16; }
			if((blue += 16) > m_fMaxHeight){ blue -= 16; }
			if((green += 16) > m_fMaxHeight){ green -= 16; }

			m_pImage->setPixel(x, y, video::SColor(255, red, green, blue));
		}
	}
}
/* */
void::CTerrain::GenerateTexture()
{
	scene::IMesh* mesh = m_pTerrain->getMesh();

	for(u32 i = 0; i < mesh->getMeshBufferCount(); ++i)
	{
		scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i);
		if(buffer->getVertexType() != video::EVT_2TCOORDS){ continue; }

		video::S3DVertex2TCoords* pVertices = (video::S3DVertex2TCoords*)buffer->getVertices();
		
		for(u32 x = 0; x < m_iDimension; ++x)
		{
			for(u32 y = 0; y < m_iDimension; ++y)
			{
				if(pVertices[(x * m_iDimension) + y].Pos.Y < (m_fMaxHeight / 9.0f)){ m_pImage->setPixel((m_iDimension - x), y, video::SColor( 255, 50, 50, 255)); }
				else if(pVertices[(x * m_iDimension) + y].Pos.Y < (m_fMaxHeight / 4.0f)){ m_pImage->setPixel((m_iDimension - x), y, video::SColor( 255, 50, 255, 50)); }
				else if(pVertices[(x * m_iDimension) + y].Pos.Y < (m_fMaxHeight / 2.2f)){ m_pImage->setPixel((m_iDimension - x), y, video::SColor( 255, 180, 180, 180)); }
				else { m_pImage->setPixel((m_iDimension - x), y, video::SColor( 255, 255, 255, 255)); }
			}
		}
	}
}
/* */
void CTerrain::OnRegisterSceneNode()
{
	if(IsVisible){ m_pSmgr->registerNodeForRendering(this); }
	scene::ISceneNode::OnRegisterSceneNode();
}
/* */
void CTerrain::OnAnimate(irr::u32 timeMs)
{
	if(IsVisible)
	{
		setVisible(false);	//Hide the Terrain
		setVisible(true);		//Show the Terrain
	}

	scene::ISceneNode::OnAnimate(timeMs);
}
/* */
void CTerrain::render()
{
}
/* */
void CTerrain::OnSetConstants(irr::video::IMaterialRendererServices *services, irr::s32 userData)
{
	video::IVideoDriver* driver = services->getVideoDriver();

	core::matrix4 view = driver->getTransform(video::ETS_VIEW);
	core::matrix4 proj = driver->getTransform(video::ETS_PROJECTION);

	core::matrix4 world = driver->getTransform(video::ETS_WORLD);

	services->setVertexShaderConstant("xView", view.pointer(), 16);
	services->setVertexShaderConstant("xWorld", world.pointer(), 16);
	services->setVertexShaderConstant("xProjection", proj.pointer(), 16);

	services->setVertexShaderConstant("xEnableLighting", false, 1);
	
	services->setPixelShaderConstant("xAmbient", &m_fAmbient, 1);
}

whan i launch the program, i get the following problem...

Error setting float array for HLSL variable

what is wrong here?!?
i need a texture for the textured terrain, but i want to get a multitextured, with 4 texture...
i need to resolve this first so... :?
CPU: AMD PHENOMII X6 1090T BE 3,2GHZ
RAM : OCZ 8GB 2*4GB DDR3 LOW VOLTAGE 1333
VGA: GeForce GTX680 2GB
HD : 500GB + 500GB + 2x1TB Raid Edition + 500GB External
Motherboard: ASUS CROSSHAIR FORMULA 4 890FX AM3
PSU: Corsair 750W
CPU Cooling: Katana 2
B@z
Posts: 876
Joined: Thu Jan 31, 2008 5:05 pm
Location: Hungary

Post by B@z »

you can pass textures by setting up to the model
you can give different layers to setMaterialTexture right?
give it from 0-3 then you can reach it from shader by:
sampler2D text1: register(s0);
sampler2D text2: register(s1);

and so on
Image
Image
Revan1985
Posts: 89
Joined: Tue May 08, 2007 4:11 pm
Location: Italy

Post by Revan1985 »

what i need to do to support more than 4 layer?
recompile irrlicht tu support 8 textures? :roll:
CPU: AMD PHENOMII X6 1090T BE 3,2GHZ
RAM : OCZ 8GB 2*4GB DDR3 LOW VOLTAGE 1333
VGA: GeForce GTX680 2GB
HD : 500GB + 500GB + 2x1TB Raid Edition + 500GB External
Motherboard: ASUS CROSSHAIR FORMULA 4 890FX AM3
PSU: Corsair 750W
CPU Cooling: Katana 2
Revan1985
Posts: 89
Joined: Tue May 08, 2007 4:11 pm
Location: Italy

Post by Revan1985 »

register(s0) is glsl, right?
i'm using hlsl ^^'
CPU: AMD PHENOMII X6 1090T BE 3,2GHZ
RAM : OCZ 8GB 2*4GB DDR3 LOW VOLTAGE 1333
VGA: GeForce GTX680 2GB
HD : 500GB + 500GB + 2x1TB Raid Edition + 500GB External
Motherboard: ASUS CROSSHAIR FORMULA 4 890FX AM3
PSU: Corsair 750W
CPU Cooling: Katana 2
B@z
Posts: 876
Joined: Thu Jan 31, 2008 5:05 pm
Location: Hungary

Post by B@z »

nope, im using hlsl too, and learned that i have to use that. but if you declare sampler2D-s it will use the correct order
for example

sampler2D first;
sampler2D second;
sampler2D third;

then the first will be the 0 layer, second will get the 1nd layer and so on.

and for supporting more textures, you need to recomplie irrlicht, just search around forums, there is a topic about it
this
Image
Image
Post Reply