I want to model a parametric surface out of a texture3D
using a GLSL shader. The texture3D is basically white everywhere (this is a simplification). From that TEXTURE3D I'm select those voxels that lie on a cylinder with parabolic base:
Vertex Shader:
varying vec3 texture_coordinate;
uniform float thickness;
uniform float curvature;
varying vec4 pvertex;
void main()
{
vec4 v=gl_Vertex;
texture_coordinate= v.xyz;
gl_Position = gl_ModelViewProjectionMatrix*v;
pvertex = v;
}
Fragment Shader:
varying vec3 texture_coordinate;
uniform sampler3D my_color_texture;
varying vec4 pvertex;
uniform float thickness;
uniform float curvature;
void main()
{
// Filter out the vertices outside a given surface normal
float parametricSurfaceEquation = (pvertex.x*pvertex.x)/curvature;
if ( distance(pvertex.xz,vec2(pvertex.x,parametricSurfaceEquation)) <= thickness )
{
gl_FragColor = vec4(1.0);
}
else
{
// color the vertices outside that small volume around the surface to black
gl_FragColor = vec4(0.0,0.0,0.0,1.0);
}
if ( ((pvertex.x*pvertex.x) + (pvertex.z*pvertex.z)) <= curvature*0.5f )
gl_FragColor = vec4(0.0);
}
but the result is that, while this works for areas where the curvature is low, on highly curved areas the surface is thicker than in lowly curved areas as shown in the following images. This is the desired situation for me:
but if I increase the thickness
parameter the center is much thicker than the peripheries.
Is it possible to avoid this problem in some way? I'm basically coloring white the voxels that are inside a small radius around the surface but I would like to specify the thickness for every area of to be the same, directed with the normal of that point.
SOLUTION Changed the shader to:
varying vec3 texture_coordinate;
uniform sampler3D my_color_texture;
varying vec4 pvertex;
uniform float thickness;
uniform float curvature;
void main()
{
// Filter out the vertices outside a given surface normal
float parametricSurfaceEquation = (pvertex.x*pvertex.x)/curvature;
float normalLength = sqrt(1.0+(2.0*pvertex.x/curvature)*(2.0*pvertex.x/curvature));
if ( abs((pvertex.z - parametricSurfaceEquation)/normalLength) <= thickness)
{
gl_FragColor = vec4(1.0);
}
else
{
// color the vertices outside that small volume around the surface to black
gl_FragColor = vec4(0.0,0.0,0.0,1.0);
}
if ( ((pvertex.x*pvertex.x) + (pvertex.z*pvertex.z)) <= curvature*0.5f )
gl_FragColor = vec4(0.0);
}
and the result is the following: