make the brush renderer draw lines well
This commit is contained in:
		
							parent
							
								
									85dce88ec2
								
							
						
					
					
						commit
						63d5c04a0d
					
				
					 1 changed files with 49 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -12,29 +12,71 @@ const linesVertexShader = `#version 300 es
 | 
			
		|||
    layout (location = 2) in vec4 a_color;
 | 
			
		||||
    layout (location = 3) in vec2 a_properties; // (thickness, hardness)
 | 
			
		||||
 | 
			
		||||
    out vec2 vf_localPosition;
 | 
			
		||||
    out vec4 vf_line;
 | 
			
		||||
    out vec4 vf_color;
 | 
			
		||||
    out vec2 vf_properties;
 | 
			
		||||
 | 
			
		||||
    void main() {
 | 
			
		||||
        float thickness = a_properties.x;
 | 
			
		||||
        float hardness = a_properties.y;
 | 
			
		||||
 | 
			
		||||
        vec2 xAxis = a_line.zw - a_line.xy;
 | 
			
		||||
        vec2 direction = normalize(xAxis);
 | 
			
		||||
        vec2 from = a_line.xy;
 | 
			
		||||
        vec2 to = a_line.zw;
 | 
			
		||||
        vec2 direction = normalize(to - from);
 | 
			
		||||
        if (to == from)
 | 
			
		||||
            direction = vec2(1.0, 0.0);
 | 
			
		||||
 | 
			
		||||
        // Extrude forward for caps
 | 
			
		||||
        from -= direction * (thickness / 2.0);
 | 
			
		||||
        to += direction * (thickness / 2.0);
 | 
			
		||||
 | 
			
		||||
        vec2 xAxis = to - from;
 | 
			
		||||
        vec2 yAxis = vec2(-direction.y, direction.x) * thickness;
 | 
			
		||||
 | 
			
		||||
        vec2 localPosition = a_line.xy + xAxis * a_position.x + yAxis * a_position.y;
 | 
			
		||||
        vec2 localPosition = from + xAxis * a_position.x + yAxis * a_position.y;
 | 
			
		||||
        vec4 screenPosition = vec4(localPosition + u_translation, 0.0, 1.0);
 | 
			
		||||
        vec4 scenePosition = screenPosition * u_projection;
 | 
			
		||||
 | 
			
		||||
        gl_Position = scenePosition;
 | 
			
		||||
        vf_localPosition = localPosition;
 | 
			
		||||
        vf_line = a_line;
 | 
			
		||||
        vf_color = a_color;
 | 
			
		||||
        vf_properties = a_properties;
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
const linesFragmentShader = `#version 300 es
 | 
			
		||||
    precision highp float;
 | 
			
		||||
 | 
			
		||||
    in vec2 vf_localPosition;
 | 
			
		||||
    in vec4 vf_line;
 | 
			
		||||
    in vec4 vf_color;
 | 
			
		||||
    in vec2 vf_properties;
 | 
			
		||||
 | 
			
		||||
    out vec4 f_color;
 | 
			
		||||
 | 
			
		||||
    // https://iquilezles.org/articles/distfunctions2d/
 | 
			
		||||
 | 
			
		||||
    float segmentSdf(vec2 uv, vec2 a, vec2 b) {
 | 
			
		||||
        vec2 uva = uv - a;
 | 
			
		||||
        vec2 ba = b - a;
 | 
			
		||||
        float h = clamp(dot(uva, ba) / dot(ba, ba), 0.0, 1.0);
 | 
			
		||||
        return length(uva - ba * h);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void main() {
 | 
			
		||||
        f_color = vec4(vec3(0.0), 1.0);
 | 
			
		||||
        float thickness = vf_properties.x;
 | 
			
		||||
        float hardness = vf_properties.y;
 | 
			
		||||
        float halfSoftness = (1.0 - hardness) / 2.0;
 | 
			
		||||
 | 
			
		||||
        vec2 uv = vf_localPosition;
 | 
			
		||||
        float alpha = -(segmentSdf(uv, vf_line.xy, vf_line.zw) - thickness) / thickness;
 | 
			
		||||
        if (hardness > 0.999)
 | 
			
		||||
            alpha = step(0.5, alpha);
 | 
			
		||||
        else
 | 
			
		||||
            alpha = smoothstep(0.5 - halfSoftness, 0.5001 + halfSoftness, alpha);
 | 
			
		||||
 | 
			
		||||
        f_color = vec4(vec3(1.0), alpha) * vf_color;
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -148,6 +190,8 @@ export class BrushRenderer {
 | 
			
		|||
        );
 | 
			
		||||
        gl.uniform2f(this.linesProgram.u_translation, this.#translation.x, this.#translation.y);
 | 
			
		||||
 | 
			
		||||
        gl.enable(gl.BLEND);
 | 
			
		||||
 | 
			
		||||
        let instances = this.linesInstanceData;
 | 
			
		||||
        instances[0] = x1;
 | 
			
		||||
        instances[1] = y1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue