Passing a texture to a shader

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
Viking86
Posts: 24
Joined: Tue Apr 20, 2010 2:29 pm

Passing a texture to a shader

Post by Viking86 »

Greetings, I've posted a similar question in the beginners forum, but it may be more appropriate in the advanced section.

I would like to implement relief mapping (which is similar to parallax but better ), i have the required GLSL code (.vert and .frag) from this example.
http://www.codesampler.com/source_users ... apping.zip

I have read the shader tutorial, however I am unsure how to pass the required textures to the shader. There is no inbuilt type of material with a heightmap as a second texture. (following the code of making a new material from the shade tutorial)

I need to pass a texture and a heightmap to the shader, any ideas on how to acomplish this?

Best regards, Daniel.
ent1ty
Competition winner
Posts: 1106
Joined: Sun Nov 08, 2009 11:09 am

Post by ent1ty »

node->setMaterialTexture(0, texture);
node->setMaterialTexture(1, heighmap);

Then you should be able to access them in the shader.
irrRenderer 1.0
Height2Normal v. 2.1 - convert height maps to normal maps

Step back! I have a void pointer, and I'm not afraid to use it!
stefbuet
Competition winner
Posts: 495
Joined: Sun Dec 09, 2007 4:13 pm
Location: france

Post by stefbuet »

And you have to give textures layer ID to the shader with the shader call back which send all uniform values.
Viking86
Posts: 24
Joined: Tue Apr 20, 2010 2:29 pm

Post by Viking86 »

Thank you for your reply
I assume i need to use the
virtual void IMaterialRendererServices::setVertexShaderConstant and
IMaterialRendererServices::setPixelShaderConstant methods
in the class MyShaderCallBack : public video::IShaderConstantSetCallBack
from the shader tutorial.

what do I put as the parameters?
The first parameter is the texture i assume, one of the shaders needs 2 textures. I'm not sure about the startregister parameter though?
freetimecoder
Posts: 226
Joined: Fri Aug 22, 2008 8:50 pm
Contact:

Post by freetimecoder »

First, you set the textures as described:

Code: Select all

node->setMaterialTexture(0, texture);
node->setMaterialTexture(1, heighmap);
In the shader callback, you now have to set the constants, depending on the uniforms in your shader. It says

Code: Select all

uniform sampler2D testTexture;
uniform sampler2D HeightTexture;
So your shader expects two textures. You can set a texture like this:

Code: Select all

int texture_height=1; 
services->setPixelShaderConstant("HeightTexture", (float*)(&texture_height), 1);
The other texture is set in the same way, you just have to change the parameters:

Code: Select all

int texture_test=0; 
services->setPixelShaderConstant("testTexture", (float*)(&texture_test), 1);
The order of the given parameters is not important, however it is better to give them in the right order, in this case it would be:

Code: Select all

int texture_test=0; 
services->setPixelShaderConstant("testTexture", (float*)(&texture_test), 1);
int texture_height=1; 
services->setPixelShaderConstant("HeightTexture", (float*)(&texture_height), 1);
This way it is easier to maintain an overview of the parameters.
greetings
Viking86
Posts: 24
Joined: Tue Apr 20, 2010 2:29 pm

Post by Viking86 »

Thank you in you replies :)

now going through the shader code there are a few more things these particular shaders need.

uniform vec4 Tangent;
uniform vec4 Normal;
uniform vec4 BiNormal;

uniform vec4 Eye; //eye coord
varying vec3 EyeDir; // eye vector direction

I know how to get these in opengl, is this posible in irrilicht?
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Post by slavik262 »

Tangents, normals, and the like should be passed in automatically since that data is coming from the vertices themselves. To set other things, you use a class derived from IShaderConstantSetCallBack and set the data with IMaterialRendererServices functions. See the shader example for details.
Viking86
Posts: 24
Joined: Tue Apr 20, 2010 2:29 pm

Post by Viking86 »

slavik262 wrote:Tangents, normals, and the like should be passed in automatically since that data is coming from the vertices themselves. To set other things, you use a class derived from IShaderConstantSetCallBack and set the data with IMaterialRendererServices functions. See the shader example for details.
I don't think that they are passed automaticly, a quote from the "per pixel lightnig tutorial" for using parallax mapping (I also have a shader for that)
But just setting color and normal map is not everything. The material we want to use needs some additional informations per vertex like tangents and binormals. Because we are too lazy to calculate that information now, we let Irrlicht do this for us.That's why we call IMeshManipulator::createMeshWithTangents().
It creates a mesh copy with tangents and binormals from another mesh. After we've done that, we simply create a standard mesh scene node with this mesh copy, set color and normal map and adjust some other material settings.
And I don't know how to access irrilicht internal parallax shader routine
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Post by slavik262 »

In the example you take a mesh without tangents and use the mesh manipulator to create a duplicate mesh with tangents, but notice how in the tutorial itself, CD3D9ParallaxMapRenderer.cpp, and COpenGLParallaxMapRenderer.cpp, there's nothing that sets the tangents in a shader callback or anything. That's because these tangents are part of the vertex information (since each vertex has one). They get passed in automatically just like position, normal, color, and UV coordinates.
Viking86
Posts: 24
Joined: Tue Apr 20, 2010 2:29 pm

Post by Viking86 »

slavik262 wrote:In the example you take a mesh without tangents and use the mesh manipulator to create a duplicate mesh with tangents, but notice how in the tutorial itself, CD3D9ParallaxMapRenderer.cpp, and COpenGLParallaxMapRenderer.cpp, there's nothing that sets the tangents in a shader callback or anything. That's because these tangents are part of the vertex information (since each vertex has one). They get passed in automatically just like position, normal, color, and UV coordinates.
Thank you very much slavik, could my problem simply be in the names in the shader code ?

I found what the uniform variables are in the shader example, RenderMonkey helped me out
Tangent (1.0,0.0,0.0,0.0)
Normal((0.0,0.0,1.0,0.0))
BiNormal(0.0,1.0,0.0,0.0)
Eye(0.0,0.0,0.0,1.0)

Now I need to pass these to the fragment shader, something similar to this i assume
video::SColorf normala(0.0f,0.0f,1.0f,0.0f);
services->setVertexShaderConstant("Normal", reinterpret_cast<f32*>(&normala), 4);

Now I am not sure if ScolorF is the best way to do this but this is my result :D

Image

Thanks again to everyone who helped !
p.s this is parallax map, relief mapping is just a bit different shader code but it is slow as hell on my laptop (1 fps)
Post Reply