PDA

View Full Version : Clamp by World-Y in vertex shader



RyuMaster
06-16-2015, 04:39 AM
Hi! I want to clamp values from 0 to 1 using Y world position, camera-independent; It work for me, but only taking camera transformation in place;

Vertex Shader

#version 130

// Uniform inputs
uniform mat4 p3d_ModelViewProjectionMatrix;

// Vertex inputs
in vec4 p3d_Vertex;
out float whiteness;


void main() {
gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
whiteness = clamp(gl_Position.y,0.0,1.0);
}

Fragment Shader:


#version 130

uniform sampler2D p3d_Texture0;
out vec4 MyFragColor;
// Input from vertex shader
in vec2 texcoord;
in float whiteness;

void main() {
MyFragColor = vec4(whiteness,whiteness,whiteness,1);
}

Now, I understand that p3d_ModelViewProjectionMatrix transforms vertex position in camera space, and I need to have it in world-space. But if I use identity matrix instead of p3d_ModelViewProjectionMatrix, I get nothing (I use identity, because I do not scale or transform object); Besides, I still need those pixel to be displayed inside camera properly, so I think I still need p3d_ModelViewProjectionMatrix, I just need to perform some additional step after it to have values clamped as I want properly?

RyuMaster
06-16-2015, 05:33 AM
For example, this code below still depends on camera position, though firstly I used p3d_ModelViewProjectionMatrix in vertex shader, and then completely reversed it using p3d_ModelViewProjectionMatrixInverse in fragment shader. Why?



#version 130

// Uniform inputs
uniform mat4 p3d_ModelViewProjectionMatrix;

// Vertex inputs
in vec4 p3d_Vertex;
in vec2 p3d_MultiTexCoord0;

// Output to fragment shader
out vec2 texcoord;

void main() {
gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
texcoord = p3d_MultiTexCoord0;

}



#version 130

uniform mat4 p3d_ModelViewProjectionMatrixInverse;
uniform sampler2D p3d_Texture0;
out vec4 MyFragColor;
// Input from vertex shader
in vec2 texcoord;


void main() {

vec4 worldSpacePositionOfScreenFragment = p3d_ModelViewProjectionMatrixInverse * vec4(texcoord.xy * 2.0 - 1.0, 0.0, 1.0);
vec3 processingPosition = vec3(worldSpacePositionOfScreenFragment.xyz/worldSpacePositionOfScreenFragment.w);


float isUnderwater = clamp(processingPosition.z, 0.0, 1.0);
MyFragColor = vec4(isUnderwater, isUnderwater, isUnderwater, 1.0);

}

carsten neumann
06-16-2015, 12:51 PM
You'll need to pass in the transformation from model space to world space (in addition to the model view projection matrix). Use an additional output from your vertex shader to pass the world position to the fragment shader.