Converting GLSL to HLSL

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
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Converting GLSL to HLSL

Post by Lambda »

Hello, i've found a nice shader but is in GLSL and i need it in HLSL.

I've been reading tuts on internet about HLSL and i still dont catch the way that shaders works, so im here requesting some help from the shaders masters.

Vertex Shader:


Code: Select all

uniform mat4 matWorldInverse; 
 
varying vec2 Texcoord; 
varying vec2 Texcoord2; 
varying vec3 ViewDirection; 
varying vec3 LightDirection1; 
    
float getLengthSQR( vec3 vec ) 
{ 
	return dot( vec, vec ); 
}

void main( void ) 
{    
	mat4 LightTransform		= gl_ModelViewMatrix; 
	LightTransform			= LightTransform * matWorldInverse; 

	gl_Position				= ftransform(); 
	Texcoord				= gl_MultiTexCoord0.xy; 
	Texcoord2				= gl_MultiTexCoord1.xy; 
		
	vec4 fvObjectPosition	= gl_ModelViewMatrix * gl_Vertex; 
	vec3 fvViewDirection	= -fvObjectPosition.xyz; 
	vec3 fvNormal			= gl_NormalMatrix * gl_Normal; 

	vec3 fvTangent			= -vec3( abs( gl_Normal.y ) + abs( gl_Normal.z ), abs( gl_Normal.x ), 0 );
	vec3 fvBinormal			= cross( fvTangent, gl_Normal ); 

	fvTangent				= gl_NormalMatrix * cross( fvBinormal, gl_Normal );
	fvBinormal				= gl_NormalMatrix * fvBinormal;   

	ViewDirection.x			= dot( fvTangent, fvViewDirection );
	ViewDirection.y			= dot( fvBinormal, fvViewDirection );
	ViewDirection.z			= dot( fvNormal, fvViewDirection );   
}
Pixel Shader:

Code: Select all

uniform vec4 fvAmbient; 
uniform vec4 fvLight1Color; 
uniform float fSpecularPower; 
uniform float fSpecularStrength; 

uniform sampler2D baseMap; 
uniform sampler2D lightMap; 
uniform sampler2D bumpMap; 

varying vec2 Texcoord; 
varying vec2 Texcoord2; 
varying vec3 ViewDirection; 

void main( void ) 
{ 
	vec3 normal				= normalize( texture2D( bumpMap, Texcoord.xy ).xyz * 2.0 - 1.0 );
	vec3 camera_dir			= normalize( ViewDirection );
	vec4 base				= texture2D( baseMap, Texcoord.xy );

	gl_FragColor			= texture2D( lightMap, Texcoord2.xy ) * ( base + pow( clamp( dot( reflect( -camera_dir, normal ),camera_dir ), 0.0, 1.0 ), fSpecularPower ) * fSpecularStrength );
}
Image
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Post by Lambda »

Sorry for the post, but since no one answers i had to start trying to conver it by my own.

But i have some problems, i have no idea to what is the equivalent of gl_Normal or gl_NormalMatrix in HLSL, anyone can give me a tip? :D
Image
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

Hi,

Instead of gl_Normal, You can use NORMAL sementic for Your variable eg:

Code: Select all

float3 Normal : NORMAL;
What with gl_NormalMatrix, You have to reproduce it and send to shader as uniform. You can reproduce it in this way:

Code: Select all

uniform mat3 gl_NormalMatrix; // transpose of the inverse of the
// upper leftmost 3x3 of gl_ModelViewMatrix
Structure of gl_NormalMatrix, You can also find it in GLSL specification.

Hope this helps,
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
wing64
Competition winner
Posts: 242
Joined: Wed Jul 23, 2008 2:35 am
Location: Thailand
Contact:

Post by wing64 »

Another key for convert between GLSL to HLSL
1. Matrix.
GLSL: vec4 pos = wvp* in_pos;
HLSL: float4 pos = mul( in_pos, wvp );
2. Varying var in GLSL equal TEXCOORDx (x = 0..n) in HLSL.
3. Some shader fx need swap Y axis opposite.
4. and many etc u will found between u learning convert by yourself. :D
cheers.
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Post by Lambda »

I have got the HLSL shader, it compiles fine but i still dont know how to finish some things :x

This is the code:

Code: Select all

float4x4 mWorldViewProj;  // World * View * Projection transformation
sampler2D tex0; // Diffuse texture
sampler2D tex1; // Lightmap
sampler2D tex2; // Normal map


// Vertex shader output structure
struct VS_OUTPUT
{
	float4 Position			: POSITION0;	// vertex position 
	float2 TexCoord			: TEXCOORD0;	// diffuse coords 
	float2 TexCoord2		: TEXCOORD1;	// lightmap coords
	float3 ViewDir			: TEXCOORD2;	// view direction
};


VS_OUTPUT vertexMain( in float4 vPosition	: POSITION,
                      in float3 vNormal		: NORMAL,
                      float2 texCoord		: TEXCOORD0,
                      float2 texCoord2		: TEXCOORD1 )
{
	VS_OUTPUT Output;

	// transform position to clip space 
	Output.Position = mul(vPosition, mWorldViewProj);
	Output.TexCoord = texCoord;
	Output.TexCoord2 = texCoord2;
	
	float3 fViewDirection				= -Output.Position.zyx;
	float3 fTangent						= -float3( abs( vNormal.y ) + abs( vNormal.z ), abs( vNormal.x ), 0.0 );
	float3 fBiNormal					= cross( fTangent, vNormal );
	fTangent							= cross( fBiNormal, vNormal ); 

	Output.ViewDir.x					= dot( fTangent, fViewDirection );
	Output.ViewDir.y					= dot( fBiNormal, fViewDirection );
	Output.ViewDir.z					= dot( vNormal, fViewDirection );
	
	return Output;
}

struct VS_INPUT
{
	float2 TexCoord : TEXCOORD0;
	float TexCoord2 : TEXCOORD1;
	float3 ViewDirection : TEXCOORD2;
};
	
float4 pixelMain( VS_INPUT input ) : COLOR0
{ 
	float3 normal				= normalize( tex2D( tex2, input.TexCoord ) * 2.0 - 1.0 );
	float3 camera_dir			= normalize( input.ViewDirection );
	float4 base					= tex2D( tex0, input.TexCoord );
	
	return tex2D( tex1, input.TexCoord2 ) * ( base + pow( clamp( dot( reflect( -camera_dir, normal ), camera_dir ), 0.0, 1.0 ), /* Power */10.0 ) * /* Strength */ 0.6 );
}
Nadro, i dont know how to achieve the thing you said, mainly because i'm not too experience with shaders or matrixs, and win64, thanks for the tips :)

The shader "works" (not as expected of course) i can see my room with the diffuse texture and the lightmap but not with the normalmap.

Actually it looks like this.

http://img9.imageshack.us/i/102009102210512275.jpg/

Original OpenGL shader (ignore the water):
http://img42.imageshack.us/i/lolsv.jpg/

As you can see there's no bumpy effect

Can someone give me a hand? :?
Image
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Post by Lambda »

I have been messing around with the tangent generation, is this code correct?

Code: Select all

	float3 fNormal						= mul( vNormal, mWorld );
	float3 fViewDirection				= -Output.Position.xyz;
	float3 fTangent						= -float3( abs( vNormal.y ) + abs( vNormal.z ), abs( vNormal.x ), 0.0 );
	float3 fBiNormal					= cross( fTangent, vNormal );
	fTangent							= mul( cross( fBiNormal, vNormal ), mWorld ); 
	fBiNormal							= mul( fBiNormal, mWorld ); 
mWorld:

Code: Select all

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

		services->setVertexShaderConstant("mWorld", matWorld.pointer(), 16);
Seriously, this is the fourth day that im trying to convert the shader to HLSL without success :x
Image
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

I think that bit is ok, you have your matrix muls the right way around. What does the rest of the shader look like? I'm guessing it compiles fine at this stage?

Remember for the textures you have to do:

Code: Select all

sampler2D tex0 : register(s0); // Diffuse texture
sampler2D tex1 : register(s1); // Lightmap
sampler2D tex2 : register(s2); // Normal map 
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Post by Lambda »

This is my full actual shader:

Code: Select all

float4x4 mWorldViewProj;  // World * View * Projection transformation
float4x4 mWorld;  // World projection
sampler2D tex0 : register(s0); // Diffuse texture
sampler2D tex1 : register(s1); // Lightmap
sampler2D tex2 : register(s2); // Normal map 


// Vertex shader output structure
struct VS_OUTPUT
{
	float4 Position			: POSITION0;	// vertex position 
	float2 TexCoord			: TEXCOORD0;	// diffuse coords 
	float2 TexCoord2		: TEXCOORD1;	// lightmap coords
	float3 ViewDir			: TEXCOORD2;	// view direction
};


VS_OUTPUT vertexMain( in float4 vPosition	: POSITION,
                      in float3 vNormal		: NORMAL,
                      float2 texCoord		: TEXCOORD0,
                      float2 texCoord2		: TEXCOORD1 )
{
	VS_OUTPUT Output;

	// transform position to clip space 
	Output.Position = mul(vPosition, mWorldViewProj);
	Output.TexCoord = texCoord;
	Output.TexCoord2 = texCoord2;
	
	float3 fNormal						= mul( vNormal, mWorld );
	float3 fViewDirection				= -Output.Position.xyz;
	float3 fTangent						= -float3( abs( vNormal.y ) + abs( vNormal.z ), abs( vNormal.x ), 0.0 );
	float3 fBiNormal					= cross( fTangent, vNormal );
	fTangent							= mul( cross( fBiNormal, vNormal ), mWorld ); 
	fBiNormal							= mul( fBiNormal, mWorld ); 

	Output.ViewDir.x					= dot( fTangent, fViewDirection );
	Output.ViewDir.y					= dot( fBiNormal, fViewDirection );
	Output.ViewDir.z					= dot( fNormal, fViewDirection );
	
	return Output;
}

struct VS_INPUT
{
	float2 TexCoord : TEXCOORD0;
	float TexCoord2 : TEXCOORD1;
	float3 ViewDirection : TEXCOORD2;
};
	
float4 pixelMain( VS_INPUT input ) : COLOR0
{ 
	float3 normal				= normalize( tex2D( tex2, input.TexCoord ) * 2.0 - 1.0 );
	float3 camera_dir			= normalize( input.ViewDirection );
	float4 base					= tex2D( tex0, input.TexCoord );
	
	return tex2D( tex1, input.TexCoord2 ) * ( base + pow( clamp( dot( reflect( -camera_dir, normal ), camera_dir ), 0.0, 1.0 ), /* Power */10.0 ) * /* Strength */ 0.6 );
}
It compiles fine but the effect is gone..

Also this is my shader callback:

Code: Select all

class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:

	virtual void OnSetConstants(video::IMaterialRendererServices* services,
			s32 userData)
	{
		video::IVideoDriver* driver = services->getVideoDriver();

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

		services->setVertexShaderConstant("mWorld", matWorld.pointer(), 16);

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

		services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16);
	}
};
And BlindSide, thanks for the samplers tip :D
Image
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Not really the solution but I noticed that "float TexCoord2 : TEXCOORD1; " should be "float2 TexCoord2 : TEXCOORD1; " in VS_INPUT.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Lambda
Posts: 126
Joined: Wed Feb 27, 2008 3:00 pm
Location: Spain, Huelva
Contact:

Post by Lambda »

BlindSide wrote:Not really the solution but I noticed that "float TexCoord2 : TEXCOORD1; " should be "float2 TexCoord2 : TEXCOORD1; " in VS_INPUT.
yes, i have fixed that but still the same :?

EDIT: Got it partially working, it only shows the bumpy effect in two walls, not in the other 4 walls, strange :shock:

http://img94.imageshack.us/img94/9167/asd1.png

as you can see, only the front (and back) walls got the effect, the other 4 walls still the same.

Code: Select all

float4x4 mWorldViewProj;  // World * View * Projection transformation
float4x4 mWorld;  // World projection
sampler2D tex0 : register(s0); // Diffuse texture
sampler2D tex1 : register(s1); // Lightmap
sampler2D tex2 : register(s2); // Normal map 


// Vertex shader output structure
struct VS_OUTPUT
{
	float4 Position			: POSITION0;	// vertex position 
	float2 TexCoord			: TEXCOORD0;	// diffuse coords 
	float2 TexCoord2		: TEXCOORD1;	// lightmap coords
	float3 ViewDir			: TEXCOORD2;	// view direction
};


VS_OUTPUT vertexMain( in float4 vPosition	: POSITION,
                      in float3 vNormal		: NORMAL,
                      float2 texCoord		: TEXCOORD0,
                      float2 texCoord2		: TEXCOORD1 )
{
	VS_OUTPUT Output;

	// transform position to clip space 
	Output.Position = mul(vPosition, mWorldViewProj);
	Output.TexCoord = texCoord;
	Output.TexCoord2 = texCoord2;
	
	float3 fNormal						= mul( vNormal, mWorld );
	float3 fViewDirection				= -Output.Position.xyz;
	float3 fTangent						= -float3( abs( vNormal.y ) + abs( vNormal.z ), abs( vNormal.x ), 0.0 );
	float3 fBiNormal					= cross( fTangent, vNormal );
	fTangent							= mul( cross( fBiNormal, vNormal ), mWorld ); 
	fBiNormal							= mul( fBiNormal, mWorld ); 

	Output.ViewDir.x					= dot( fTangent, fViewDirection );
	Output.ViewDir.y					= dot( fBiNormal, fViewDirection );
	Output.ViewDir.z					= dot( fNormal, fViewDirection );
	
	return Output;
}

struct VS_INPUT
{
	float2 TexCoord : TEXCOORD0;
	float2 TexCoord2 : TEXCOORD1;
	float3 ViewDirection : TEXCOORD2;
};
	
float4 pixelMain( VS_INPUT input ) : COLOR0
{ 
	float3 normal				= normalize( tex2D( tex2, input.TexCoord ).xyz * 2.0 - 1.0 );
	float3 camera_dir			= normalize( input.ViewDirection );
	float4 base					= tex2D( tex0, input.TexCoord );
	
	return tex2D( tex1, input.TexCoord2 ) * ( base + pow( clamp( dot( reflect( -camera_dir, normal ), camera_dir ), 0.0, 1.0 ), /* Power */10.0 ) * /* Strength */ 0.6 );
}
mWorld = driver->getTransform(video::ETS_WORLD)
Image
Post Reply