[SOLVED] Extracting pixel's worldspace position

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!
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

Eureka.... I found extracting worldspace pos has been done before in SSAO in Xeffects... all i need to do is copy and adapt.
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

I think I made it

Code: Select all

// simple fragment shader
uniform sampler2D DM;
uniform float FarValue;
uniform mat4 reverseScreenVP;
uniform float xDist;
uniform vec4 point;

void main()
{
	vec2 texcoord = vec2(gl_TexCoord[0]);
	vec4 texDepth = texture2D(DM, texcoord);
	float depth = (texDepth.r + texDepth.g / 256.0)*FarValue;
    texcoord -= vec2(0.5,0.5);
    texcoord *= 2.0;
    texcoord.y = - texcoord.y;
	vec4 ScreenPos = vec4(texcoord.x*depth, texcoord.y*depth, depth, 1.0);
    ScreenPos = reverseScreenVP*ScreenPos;
    if (ScreenPos.y > xDist) gl_FragColor = vec4(1.0);
}
The white bits correspond to world space coords
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

wrong doesnt work at all....

something I need to do with matrices maybe
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

ok I think I am able to retrieve the screen position coords (the one after multiplying model space gl_Vertex with gl_ModelViewMatrix)

the shader I used for terrain (quick mod)

Code: Select all

uniform float MaxD;
uniform float s;
uniform float s2;
uniform vec4 sunDiffuse;
uniform sampler2D Tex;
uniform sampler2D Tex2;
varying vec4 pos;
varying vec3 normal;
varying vec4 Sunpos;
varying vec4 Moonpos;
varying float night;

void main() 
{
	float depth = pos.z / MaxD;
	float mulDepth = depth * 256.0 + 2.0;
	float flooredDepth = floor(mulDepth);

	float shade = max(dot(Sunpos,normal),0.0)*night;
	float moonlit = max(dot(Moonpos,normal),0.0)*(1.0-night);

	vec4 tex = texture2D(Tex, gl_TexCoord[0].xy*s) * texture2D(Tex2, gl_TexCoord[0].xy*s2);
        float diffuse = gl_FrontMaterial.diffuse*sunDiffuse;
	vec4 globalAmbient = tex*gl_LightModel.ambient * gl_FrontMaterial.ambient;

	gl_FragData[0] = vec4(vec3(pos/MaxD),1.0)/*vec4(tex.rgb*shade*diffuse+globalAmbient + tex.rgb*moonlit*gl_FrontMaterial.ambient,1.0 )*/;
	gl_FragData[1] = vec4(flooredDepth / 256.0, mulDepth - flooredDepth, 0.0, 1.0 );
}
Image


And the shader I used in Shader Maker

Code: Select all

// simple fragment shader
uniform sampler2D DM; // DM for Depth Map
uniform sampler2D color;
uniform float FarValue;
uniform mat4 reverseScreenVP;

void main()
{
	vec2 texcoord = vec2(gl_TexCoord[0]);
	vec4 texDepth = texture2D(DM, texcoord);
	float depth = (texDepth.r + texDepth.g / 256.0)*FarValue;
    texcoord -= vec2(0.5,0.5);
    texcoord *= 2.0;
    texcoord.y = - texcoord.y;
	vec4 ScreenPos = vec4(texcoord.x*depth, texcoord.y*depth, depth, 1.0);
    //ScreenPos = reverseScreenVP*ScreenPos;
    ScreenPos /= FarValue;
    gl_FragColor = ScreenPos;
}
Image

as you can see they do match up
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

SO I just need confirmation if ANYONE BOTHERS to reply...

did I manage to retrieve screen space position?
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

just another way I thought of

Code: Select all

// simple fragment shader

// 'time' contains seconds since the program was linked.
uniform vec3 norm0,norm1,norm2,norm3, cameraPos;
uniform sampler2D DepthMapSampler, col;
uniform float FarLink;

vec3 getScreenNormal( void ) {
	vec3 left = mix(norm1-cameraPos, norm0-cameraPos, gl_TexCoord[0].y);
	vec3 right = mix(norm3-cameraPos, norm2-cameraPos, gl_TexCoord[0].y);
	return mix(left, right, gl_TexCoord[0].x);
}

float getDepth( void )
{
	vec4 texDepth = texture2D(DepthMapSampler, gl_TexCoord[0].xy);
	float extractedDepth = (texDepth.r + texDepth.g / 256.0);
	return extractedDepth;
}

void main()
{
	
	vec3 pos = getScreenNormal()*getDepth()/*FarLink*/+cameraPos;
	if (pos.y >700.0) gl_FragColor = texture2D(col,gl_TexCoord[0].xy);
}
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

IDIOTIC and dead simple

Code: Select all

uniform vec3 norm0,norm1,norm2,norm3, cameraPos;
uniform sampler2D DepthMapSampler, col;

vec3 getScreenNormal( void ) {
	vec3 left = mix(norm1, norm0, gl_TexCoord[0].y);
	vec3 right = mix(norm3, norm2, gl_TexCoord[0].y);
	return mix(left, right, gl_TexCoord[0].x);
}

float getDepth( void )
{
	vec4 texDepth = texture2D(DepthMapSampler, gl_TexCoord[0].xy);
	float extractedDepth = (texDepth.r + texDepth.g / 256.0);
	return extractedDepth;
}

void main()
{
	
	vec3 pos = mix(cameraPos, getScreenNormal(), getDepth()/7);
	if (pos.y >2150.0) gl_FragColor = texture2D(col,gl_TexCoord[0].xy);
}
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

Why You don't use "Edit" function? Forum isn't a trash...
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

sorry :D i was a bit overexcited
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Heh cool that's the way I used in the end too, passing 4 direction vectors and lerping based on screen pos. Nice. If you look at the shader source for XEffects SSAO you can see it there, would have saved you some time.

Wait whats with the "vec3 pos = mix(cameraPos, getScreenNormal(), getDepth()/7); ", shouldn't you be doing "vec3 pos = cameraPos + getScreenNormal() * getDepth() * farValue;"??
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

i had a look at your source code.. but it kinda didnt work for me and my method is a bit faster. I dont have to substract camPos from each position of the far plane to make a normal. I tell you how it works

After you interpolated a coordinate in WSpace (not a normal) on the far plane...
Imagine a line between that point and camera position, and a slider going between them. I use the mix function to "move the slider" and its ideal since the depth read off the depthMap is clamped in 0.0 to 1.0;

The /7 was there because my depth map was made with a MaxDistance of 10000 when my far value was 70000
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

Just to share with you my success

Image

I used reconstruction of pixel coords to do that in the water shader, it casts caustics on everything... No more playing "Receiver", "emitter"
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

Looking pretty good there devsh
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

Imagine a line between that point and camera position, and a slider going between them. I use the mix function to "move the slider" and its ideal since the depth read off the depthMap is clamped in 0.0 to 1.0;
Depth isn't linear?
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

how about it works cause i have tested retrieving positions and heights
Post Reply