본문으로 건너뛰기

varying 변수와 보간_WebGL 노트 7

무료2016-01-01#JS#WebGL#webgl varying#webgl interpolation#webgl interpolate#webgl内插

varying 변수를 이용하여 그라데이션 효과를 실현할 수 있으며, 다양한 입수할 수 없는 데이터를 보간할 수도 있다

앞에 쓰는 말

[이전 노트](/articles/7 种 webgl 图元-webgl 笔记 6/) 에서, 7 종류의 도형을 인식하고, 파라미터를 변경하면 다른 것을 그릴 수 있음을 배웠지만, 구체적인 상세는 충분히 설명되지 않았습니다. 이는 셰이더의 동작 원리에서 말할 필요가 있으며, varying 변수는 정점 셰이더와 프래그먼트 셰이더 간의 데이터 채널로서, 피할 수 없는 화제입니다

一.varying 변수

이전에 2 종류의 셰이더 변수를 설명했습니다: attribute 변수, uniform 변수.varying 변수는 마지막 1 종류의 셰이더 변수로, 앞 2 개보다 조금 더 복잡합니다. 보간 (interpolate) 프로세스가 있기 때문입니다

varying 변수의 작용은 정점 셰이더에서 프래그먼트 셰이더로 값을 전달하는 것입니다.varying 변수는 float 타입만 가능합니다.프래그먼트 셰이더 중에도 동명의 varying 변수를 선언하면, 정점 셰이더가 해당 변수에 대입한 값은 자동으로 프래그먼트 셰이더에 전달됩니다 (프래그먼트 셰이더 중의 동명 varying 변수에 대입하기 전에, 보간의 프로세스가 있으며, 1.0 이 전달되어도 반드시 1.0 은 아닙니다)

주의: 정점 셰이더 중의 varying 변수의 값은 직접 전달되지 않으며, 먼저 보간이 수행됩니다.보간은 보간 애니메이션과 같습니다

二.보간 (interpolate)

보간값은, 데이터가 부족하고 있는 경우에만 필요합니다.예를 들어, 일련의 산점을 매끄러운 곡선으로 연결하고 싶은 경우, 인접하는 기지점 사이에 많은 점이 부족하여, 이 때 보간을 통해 부족하고 있는 데이터를 메우고, 최종적으로 매끄러운 곡선상의 기지점 이외의 모든 점은 보간값에 의해 얻어집니다

예를 들어 Photoshop 의 커스텀 그라데이션에서, 우리는 수점의 색을 설정하는 것만으로 자동으로 1 본 전체의 그라데이션 대를 생성할 수 있습니다.이들 수점 사이의 색은 모두 내장 보간 알고리즘에 의해 얻어집니다

varying 변수의 값이 프래그먼트 셰이더에 전달되기 전에 수행되는 보간 프로세스는보간이라고 불립니다.마찬가지로, 우리는 보간을 이용하여 그라데이션을 생성할 수도 있습니다

三.그라데이션 삼각형

프래그먼트 셰이더 중에 정점 셰이더의 varying 변수와 동명의 varying 변수를 선언하면, 값은 자동으로 전달됩니다 (물론, 보간의 프로세스가 있습니다)

###1.셰이더 소스 프로그램

프래그먼트 셰이더 중에 동명 varying 변수를 선언합니다.구체적으로는 다음과 같습니다:

// 정점 셰이더 소스 프로그램
var vsSrc = 'attribute vec4 a_Position;' +
    'attribute vec4 a_Color;' +
    'varying vec4 v_Color;' +       // varying 변수를 선언
    'void main() {' +
    'gl_Position = a_Position;' +   // 좌표를 설정
    'gl_PointSize = 7.0;' +         // 사이즈를 설정
    'v_Color = a_Color;' +          // varying 변수에 값을 대입
'}';
// 프래그먼트 셰이더 소스 프로그램
//!!! 부동 소수점 정밀도를 선언해야 합니다.否则报错 No precision specified for (float) 
var fsSrc = 'precision mediump float;' +
    'varying vec4 v_Color;' +   // 동명 varying 변수를 선언
    'void main() {' +
    'gl_FragColor = v_Color;' + // 색을 설정
'}';

주의: varying 변수에 직접 값을 대입할 수 없습니다.attribute 변수를 통해 외부 값을 받아들이고, 정점 셰이더 내부에서 varying 변수에 값을 대입해야 합니다

###2.단색 삼각형과 그라데이션 삼각형

열쇠는 3 개의 정점의 색이 일치하는지 여부입니다.실제 프로세스는 다음과 같습니다:

  1. 정점 정보를 읽는다 (좌표, 색 등)

정점 셰이더를 실행하고, 1 개의 정점의 관련 데이터를 읽는다

  1. 도형 조립 (점을 그리는가 선을 그리는가 삼각을 그리는가)

고립된 정점 좌표를 기하 도형으로 조립한다.도형의 카테고리는 gl.drawArrays 의 첫 번째 파라미터에 의해 결정된다.예를 들어 gl.POINTS, gl.TRIANGLES

  1. 래스터라이즈 (어느 픽셀에 착색할 필요가 있는지를 확정)

조립好的 기하 도형을 프래그먼트로 변환하고, 벡터의 기하 도형을 래스터라이즈된 프래그먼트 (픽셀) 로 변환한다

  1. 프래그먼트 셰이더를 실행 (착색)

각 프래그먼트에 착색한다

  1. 첫 번째 스텝으로 돌아가, 읽었으면 종료하고, 끝나지 않으면 다음 정점을 읽고 다시 한 번 수행한다

따라서 정점 셰이더는정점마다실행되고, 프래그먼트 셰이더는프래그먼트마다실행됩니다.2 중 루프와 같은 것으로, 외층은 정점을遍历하고, 내층은 프래그먼트를遍历합니다.이상의 프로세스는 아래 그림과 같습니다:

[caption id="attachment_913" align="alignnone" width="773"]webgl-vertex-shader-execution webgl-vertex-shader-execution[/caption]

[caption id="attachment_914" align="alignnone" width="738"]webgl-varying webgl-varying[/caption]

이전의 DEMO 에서는 색은 모두 프래그먼트 셰이더 중에 하드코딩되어 있었습니다.예를 들어 gl_FragColor = vec4(1.0, 0.0, 1.0, 0.75).따라서 그려진 모든 것은 단색이었습니다.하지만 보다 과학적인 방법은 정점색을 정점 셰이더에 전달하고, 정점색에 기반하여 각 프래그먼트의 색을 보간하는 것입니다.예를 들어 1 본의 고립 선분을 그리는 경우, 2 개의 동색 정점 사이의 프래그먼트는 보간 후 모두 그 색이 되고, 2 개의 이색 정점 사이의 프래그먼트는 보간 후 다른 색이 나타납니다

###3.그라데이션 삼각형의 그리기

3 개의 정점을 다른 색으로 설정합니다.다음과 같습니다:

var arrVtx = new Float32Array([
    // x, y, r, g, b
    -0.5, 0.5, 1.0, 0.0, 1.0, 1.0,  // 적색
    0.5, 0.5, 0.0, 1.0, 0.0, 1.0,   // 녹색
    -0.5, -0.5, 0.0, 0.0, 1.0, 1.0  // 청색
]);
//...정점 배열을 버퍼에 기입
// 점을 그리기
gl.drawArrays(gl.POINTS, 0, arrVtx.length / 6);
setTimeout(function() {
    gl.clear(gl.COLOR_BUFFER_BIT);
    // 삼각형을 그리기
    gl.drawArrays(gl.TRIANGLES, 0, arrVtx.length / 6);
}, 2000);

먼저 3 개의 고립점 (적녹청) 을 그리기하고, 2 초 후에 삼각형을 그리기하면, 그라데이션 삼각형이 나타납니다.이것도 gl_PointSize 의 설정은 draw point 시에만 유효하고, 삼각형을 그리기하면 자동으로 해당 값을 무시하는 것을 설명하고 있습니다

四.DEMO

이상의 코드를 포함한 완전한 예는, 이하를 참조하십시오:

좌표에 기반하여 프래그먼트 색을 설정하고, 프래그먼트 셰이더가 프래그먼트마다 실행되는 프로세스를 검증

주의: 프래그먼트 셰이더의 내장 변수 gl_FragCoord 는 프래그먼트의 좌표 정보 (gl_FragCoord.x, gl_FragCoord.y) 를 보존하고 있습니다.출력할 수 있는 경우, 프래그먼트 셰이더가 정점마다 실행되는 프로세스가 발견되지만, API 는 console 에 정보를 출력하는 방법을 제공하고 있지 않습니다.프래그먼트 좌표에 기반하여 색을 설정함으로써 검증할 수 있습니다

五.정리

varying 변수는 그라데이션 효과를 실현할 수 있을 뿐만 아니라, 그것을 이용하여 다양한 입수할 수 없는 수치를 보간할 수도 있습니다.예를 들어 프래그먼트의 월드 좌표, 프래그먼트의 광원 좌표계 중의 좌표 등, 매우 유용합니다

우리는 현재 컬러 도형을 그릴 수 있습니다.색과 관련된 또 하나의 특성은 텍스처 (텍스처 매핑) 입니다.이는 차회의 노트의 내용입니다

참고 자료

  • 『WebGL 프로그래밍 가이드』

댓글

아직 댓글이 없습니다

댓글 작성