webgl边框颜色着色器 [英] webgl border color shader

查看:91
本文介绍了webgl边框颜色着色器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何编写着色器以纯色绘制多边形,并以不同的颜色绘制边框.

How do I write a shader to draw a polygon in solid color and it's border in a different color.

基本上,我在3d中有一个六边形贴图,如果用户要求,我需要能够用黑色边框勾勒出每个六边形.如果我可以控制边框宽度,那也很好.

Basically I have a hexagons map in 3d and I need to be able to outline each hexagon with a black border, if user requests so. Would also be nice if I could control border width.

谢谢.

推荐答案

一种方法是在中心位置创建第7个顶点的十六进制

Off the top of my head, one way would be to create a your hex with a 7th vertex in the center

   1---2
  /\   /\
 /  \ /  \
6----0----3
 \  / \  /
  \/   \/
   5---4

添加纹理坐标,其中点0具有UV = {0,0},点1,2,3,4,5,6具有UV坐标{0,1}.

Add texture coordinates where point 0 has UV = { 0, 0 } and points 1, 2, 3, 4, 5, 6 have UV coords { 0, 1 }.

然后让您的着色器根据V选择一种类似这样的颜色

Then have your shader choose a color based on V something like this

顶点着色器

attribute vec2 a_texCoord;
varying vec2 v_texCoord;
...

void main() {
  ...
  v_texCoord = a_texCoord; // pass texcoord to fragment shader
}

片段着色器

...
varying vec2 v_texCoord;
uniform vec4 u_baseColor;
uniform vec4 u_borderColor;
uniform float u_borderThickness;  // 0-1
...
void main() {
  // make a value that's 0 if less than u_borderThickness and 1 if greater
  float mixAmount = step(u_borderThickness, v_texCoord.v);

  // choose the base or border color
  gl_FragCoord = mix(u_baseColor, u_borderColor, mixAmount);
}

我想您实际上并不需要2个坐标,因为U无关紧要,您可以只使用1个

I suppose you don't actually need 2 coordinates, you can just use 1 since U is irrelevant

var canvas = document.getElementById("c");
var gl = canvas.getContext("webgl");

var prg = webglUtils.createProgramFromScripts(gl, ["vs", "fs"]);

var positionLoc = gl.getAttribLocation(prg, "a_position");
var vLoc = gl.getAttribLocation(prg, "a_v");
var baseColorLoc = gl.getUniformLocation(prg, "u_baseColor");
var borderColorLoc = gl.getUniformLocation(prg, "u_borderColor");
var borderSizeLoc = gl.getUniformLocation(prg, "u_borderSize");


var positions = [];
var vs = []

for (var ii = 0; ii < 6; ++ii) {
  var angle1 = (ii + 0) * Math.PI * 2 / 6;
  var angle2 = (ii + 1) * Math.PI * 2 / 6;
  positions.push(
    0, 0,
    Math.cos(angle1), Math.sin(angle1),
    Math.cos(angle2), Math.sin(angle2)
  );
  vs.push(0, 1, 1);
};

var positionBuf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuf);
gl.bufferData(gl.ARRAY_BUFFER, 
              new Float32Array(positions),
              gl.STATIC_DRAW);
gl.enableVertexAttribArray(positionLoc);
gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, 
                       false, 0, 0); 

var vBuf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vBuf);
gl.bufferData(gl.ARRAY_BUFFER, 
              new Float32Array(vs),
              gl.STATIC_DRAW);
gl.enableVertexAttribArray(vLoc);
gl.vertexAttribPointer(vLoc, 1, gl.FLOAT, 
                       false, 0, 0); 


function render() {
  gl.clearColor(0,0,0,0);
  gl.clear(gl.COLOR_BUFFER_BIT);

  gl.useProgram(prg);
  gl.uniform4fv(baseColorLoc, [1, 0, 0, 1]);
  gl.uniform4fv(borderColorLoc, [0, 0, 0, 1]);
  
  var t = Date.now() * 0.001;
  gl.uniform1f(borderSizeLoc, Math.sin(t) * 0.5 + 0.5);
  
  gl.drawArrays(gl.TRIANGLES, 0, 6 * 3);
  
  requestAnimationFrame(render);
}


render();

<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>

<script id="vs" type="foo">
attribute vec4 a_position;
attribute float a_v;

varying float v_v;

void main() {
  // PS: In a real WebGL app you'd probably need to multiply a_position by 
  // a matrix at a minimum

  gl_Position = a_position;
  v_v = a_v;
}
</script>

<script id="fs" type="foo">
precision mediump float;

varying float v_v;

uniform float u_borderSize;
uniform vec4 u_baseColor;
uniform vec4 u_borderColor;

void main() {
   float mixAmount = step(u_borderSize, v_v);
   gl_FragColor = mix(u_baseColor, 
                      u_borderColor, 
                      mixAmount);
}
</script>

<canvas id="c" width="256" height="256"></canvas>

这篇关于webgl边框颜色着色器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆