I'm struggling with handling Coord in fragment Shader.
In brief, I just want to draw circle with fragment shader using (x,y,z) of world space. But because of camera position and the z of circle's center position, I cannot get actual right projected x and y coords.
Let's suppose that my camera placed at (0, 0, 1000) and perspective with
- fov: 45deg
- aspect with
screen_width/screen_height - nearZ: 1
- farZ: 10000
Camera look at (0,0). In this case with three.js, I can get projectionMatrix and ModelViewMatrix of camera(e.g.PerspectiveCamera.projectionMatrix) and also in default I can use viewMatrix in fragmentShader of ShaderMaterial in three.js.
So in fragmentShader, for calculating projected coordinate of circle placed (300, 300, -1000), I write my VertexShader and FragmentShader like below.
My Vertex Shader is only for get projectionMatrix and modelViewMatrix as P and MV.
// vertexShader
varying mat4 P;
varying mat4 MV;
void main(){
P = projectionMatrix;
MV = modelViewMatrix;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
And then, I just calculate x and y using P and MV like below.
// fragmentShader
varying mat4 P;
varying mat4 MV;
uniform float x;
uniform float y;
uniform float z;
uniform float r;
uniform vec2 u_resolution;
float circle(vec2 _st, vec2 _center, float _radius){
vec2 dist = _st - _center + u_resolution;
return 1.-smoothstep(_radius-(_radius*0.01),
_radius+(_radius*0.01),
length(dist));
}
void main(){
vec2 coord = (P * MV * vec4(x, y, z, 1.0)).xy;
float point = circle(gl_FragCoord.xy, coord, r); // ignore r scaling.
gl_FragColor = vec4(vec4(point), point);
}
But the result doesn't match what I expected. And also some weird behaviors were found.
- No matter what
zof uniform, there's no change at all. - Pixel ratio can be some reason(e.g. retina display has pixel ratio as 2) but from my experiments of it, it has nothing to do with this.
Any mistake that I made? Or any misleading? (somehow there can be mistake in circle function but I think it doesn't make critical problem..)

u_resolutionand what do you expect by_st - _center + u_resolution? Shouldn't it be something like(_st - _center) / u_resolution? And note,gl_FragCoord.xyare window (pixel) coordinates. - Rabbid76(x,y)and because gl_FragCoord start at (0,0) from left bottom corner, I added u_resolution(It's also because the_centeris coordinates from (0,0) meaning center of screen. - hwloomvaryings? - derhassuniforms to begin with, so they are already available to all shader stages in the program, and passing them asvaryings is just a huge waste of ressources. - derhass