[GLSL] How to set sampler2D

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
Masterhawk
Posts: 299
Joined: Mon Nov 27, 2006 6:52 pm
Location: GERMANY
Contact:

[GLSL] How to set sampler2D

Post by Masterhawk »

hey guys,
I guess the question easy to answer for some of the shader pros around here.

1. How do I set a "uniform sampler2d" with a general texture, loaded in irrlicht, in a shader through my irrlicht app?

2. How do I tell my shader that the sampler2d should be the framebuffer?

hope you can help me


EDIT:
Here're a bit more information what I want to achieve
I just want to get a simple GLSL Glass-Shader working.

RefractionMap should be the Framebuffer and the EnvMap should be an arbitrary texture.

Code: Select all

//
// Vertex shader for environment mapping with an
// equirectangular 2D texture and refraction mapping
// with a background texture blended together using
// the fresnel terms
//
// Author: Jon Kennedy, based on the envmap shader by John Kessenich, Randi Rost
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//

varying vec3  Normal;
varying vec3  EyeDir;
varying vec4  EyePos;
varying float LightIntensity;

uniform vec3  LightPos;

void main(void) 
{
    gl_Position    = ftransform();
    Normal         = normalize(gl_NormalMatrix * gl_Normal);
    vec4 pos       = gl_ModelViewMatrix * gl_Vertex;
    EyeDir         = pos.xyz;
    EyePos		   = gl_ModelViewProjectionMatrix * gl_Vertex;
    LightIntensity = max(dot(normalize(LightPos - EyeDir), Normal), 0.0);
}

Code: Select all

//
// Fragment shader for environment mapping with an
// equirectangular 2D texture and refraction mapping
// with a background texture blended together using
// the fresnel terms
//
// Author: Jon Kennedy, based on the envmap shader by John Kessenich, Randi Rost
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//

const vec3 Xunitvec = vec3 (1.0, 0.0, 0.0);
const vec3 Yunitvec = vec3 (0.0, 1.0, 0.0);

uniform vec3  BaseColor;
uniform float Depth;
uniform float MixRatio;

// need to scale our framebuffer - it has a fixed width/height of 2048
uniform float FrameWidth;
uniform float FrameHeight;

uniform sampler2D EnvMap;
uniform sampler2D RefractionMap;

varying vec3  Normal;
varying vec3  EyeDir;
varying vec4  EyePos;
varying float LightIntensity;

void main (void)
{
    // Compute reflection vector
    vec3 reflectDir = reflect(EyeDir, Normal);

    // Compute altitude and azimuth angles

    vec2 index;

    index.y = dot(normalize(reflectDir), Yunitvec);
    reflectDir.y = 0.0;
    index.x = dot(normalize(reflectDir), Xunitvec) * 0.5;

    // Translate index values into proper range

    if (reflectDir.z >= 0.0)
        index = (index + 1.0) * 0.5;
    else
    {
        index.t = (index.t + 1.0) * 0.5;
        index.s = (-index.s) * 0.5 + 1.0;
    }
    
    // if reflectDir.z >= 0.0, s will go from 0.25 to 0.75
    // if reflectDir.z <  0.0, s will go from 0.75 to 1.25, and
    // that's OK, because we've set the texture to wrap.
  
    // Do a lookup into the environment map.

    vec3 envColor = vec3 (texture2D(EnvMap, index));
    
    // calc fresnels term.  This allows a view dependant blend of reflection/refraction
    float fresnel = abs(dot(normalize(EyeDir), Normal));
    fresnel *= MixRatio;
    fresnel = clamp(fresnel, 0.1, 0.9);

	// calc refraction
	vec3 refractionDir = normalize(EyeDir) - normalize(Normal);

	// Scale the refraction so the z element is equal to depth
	float depthVal = Depth / -refractionDir.z;
	
	// perform the div by w
	float recipW = 1.0 / EyePos.w;
	vec2 eye = EyePos.xy * vec2(recipW);

	// calc the refraction lookup
	index.s = (eye.x + refractionDir.x * depthVal);
	index.t = (eye.y + refractionDir.y * depthVal);
	
	// scale and shift so we're in the range 0-1
	index.s = index.s / 2.0 + 0.5;
	index.t = index.t / 2.0 + 0.5;
	
	// as we're looking at the framebuffer, we want it clamping at the edge of the rendered scene, not the edge of the texture,
	// so we clamp before scaling to fit
	float recip1k = 1.0 / 2048.0;
	index.s = clamp(index.s, 0.0, 1.0 - recip1k);
	index.t = clamp(index.t, 0.0, 1.0 - recip1k);
	
	// scale the texture so we just see the rendered framebuffer
	index.s = index.s * FrameWidth * recip1k;
	index.t = index.t * FrameHeight * recip1k;
	
    vec3 RefractionColor = vec3 (texture2D(RefractionMap, index));
    
    // Add lighting to base color and mix
    vec3 base = LightIntensity * BaseColor;
    envColor = mix(envColor, RefractionColor, fresnel);
    envColor = mix(envColor, base, 0.2);

    gl_FragColor = vec4 (envColor, 1.0);
}
Last edited by Masterhawk on Fri Jan 16, 2009 2:22 pm, edited 1 time in total.
Image
Masterhawk
Posts: 299
Joined: Mon Nov 27, 2006 6:52 pm
Location: GERMANY
Contact:

Post by Masterhawk »

Damn, no one out there who can help me?

I found out how to set a simple uniform sampler2d variable, but the second question still is active. How can I set the framebuffer as a sampler2d through irrlicht.


Here's the solution for the first problem I've found around the forum

Code: Select all

//setting up the texture you want to use in the shader
model->setMaterialTexture(0,driver->getTexture("textures/sampler.jpg"));

//using this code inside the shader callback
int tex_1 = 0; //the index you previously set up the texture
services->setPixelShaderConstant("samplerMap",(float*)(&tex_1),1);
Image
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

You cannot use the framebuffer as direct source (except via some extensions maybe). Just use a Render texture.
Masterhawk
Posts: 299
Joined: Mon Nov 27, 2006 6:52 pm
Location: GERMANY
Contact:

Post by Masterhawk »

well, now i've so, but I still getting no glass-refraction effect.

That's the way I create the RTT, but the shader don't recognize it.

Code: Select all

ITexture* RTTTex = driver->createRenderTargetTexture(dimension2di(2048,2048));
	teapot->setMaterialTexture(1,driver->getTexture("textures/house.jpg"));
teapot->setMaterialTexture(0,RTTTex);

//[...]
while(device->run())
	{
		driver->beginScene(true,true,SColor(0,0,0,0));
		
		driver->setRenderTarget(RTTTex, true, true);

		teapot->setVisible(false);
		smgr->drawAll();

		driver->setRenderTarget(0, true, true);

		teapot->setVisible(true);
		smgr->drawAll();

		env->drawAll();

		driver->endScene();
	}
I added the vertex shader to the first post. Would be glad if someone could test it with the following values:

LightPos = (0.0,0.0,4.0)
BaseColor = (0.4,0.4,1.0)
Depth = 0.1
MixRatio = 1.0
FrameWidth = 255.0
FrameHeight = 255.0
EnvMap = AnyEnvironmentMap
RefractionMap = the RTT texture
Image
FuzzYspo0N
Posts: 914
Joined: Fri Aug 03, 2007 12:43 pm
Location: South Africa
Contact:

Post by FuzzYspo0N »

As a matter of interest are you passing the texture to the shader via a mesh? Blindside "The guru" has explained this to me more easily lately,

Shaders operate as a material, ON A MESH. So, when i have a mesh the vertex shaders passes over the verts in my mesh (giving information like TEXCOORD0; NORMAL0; and POSITION0; This makes sense right? It also passes the texture into the shader in a "stack" form.

A mesh in irrlicht has material under meshSceneNode->getMaterial(0) or, iterating through them if there are more.

The material has textures, in stages. Each stage corresponds to a single "register" in the shader. This means that

Code: Select all

void  setTexture (u32 i, ITexture *tex) 
  Sets the i-th texture. 
On the mesh, will help set the shader textures for us. So :

meshSceneNode->getMaterial(0)->setTexture(2, ITexture*);

sets the second register in our shader. in hlsl this equates to :

sampler2d texture1 : register(s2); <- the s2 being our texture 2.

I dont know the equivalent for glsl right now, as i am learning this currently. Please post any thing you find as im sure its helpful.

Also, this means that the RTT you have has an ITexture assosicated with it,Set it to a "register/stage" and let the shader find it. You might need the setPixelShaderConstant( texture id thingy ) in glsl, but with hlsl so far i didnt have to.
Masterhawk
Posts: 299
Joined: Mon Nov 27, 2006 6:52 pm
Location: GERMANY
Contact:

Post by Masterhawk »

First of all, thx for your post :)
FuzzYspo0N wrote:As a matter of interest are you passing the texture to the shader via a mesh? [...]
Yes I do, that's what I do with

Code: Select all

teapot->setMaterialTexture(1,driver->getTexture("textures/house.jpg"));
teapot->setMaterialTexture(0,RTTTex); 
I copied the way how to transmit the textures from the soure of this post
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=27054

And since the shader works like a charm in the GLSL Demo I'm definitely confused what I'm doing wrong

The shader consits of a simple texture mixing, isn't it?


For me this part of the fragmentshader seems to be fitted to the use of the framebuffer as direct input.

Code: Select all

// scale and shift so we're in the range 0-1
	index.s = index.s / 2.0 + 0.5;
	index.t = index.t / 2.0 + 0.5;
	
	// as we're looking at the framebuffer, we want it clamping at the edge of the rendered scene, not the edge of the texture,
	// so we clamp before scaling to fit
	float recip1k = 1.0 / 2048.0;
	index.s = clamp(index.s, 0.0, 1.0 - recip1k);
	index.t = clamp(index.t, 0.0, 1.0 - recip1k);
	
	// scale the texture so we just see the rendered framebuffer
	index.s = index.s * FrameWidth * recip1k;
	index.t = index.t * FrameHeight * recip1k;
Image
Masterhawk
Posts: 299
Joined: Mon Nov 27, 2006 6:52 pm
Location: GERMANY
Contact:

Post by Masterhawk »

Finally I made it ;)

Image

Just had to change the 2048.0 in the sahder into a 255.0.
But the main problem was my program due to the fact that it corrupted the values it should transmit anywhere.
I guess this needs a closer look. Thx to you guys for your help :)
Image
FuzzYspo0N
Posts: 914
Joined: Fri Aug 03, 2007 12:43 pm
Location: South Africa
Contact:

Post by FuzzYspo0N »

Hey that looks great. Nice progress !
ugluk
Posts: 6
Joined: Sat Jan 24, 2009 2:15 pm

Post by ugluk »

Sorry for pitching in, but where did you get this shader example? I am desperate for examples!! :(
Post Reply