本文介绍了在片段着色器中创建渐变颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图实现与设计应用程序(例如Photoshop)一样的渐变颜色,但无法获得我想要的确切结果.

I'm trying to achieve making a gradient color as the design apps (Photoshop for example) does, but can't get the exact result i want.

我的着色器创建了非常漂亮的渐变",但还包含与我要切换的颜色不同的其他颜色.

My shader creates very nice 'gradients' but also contains other colors that are different from the colors I want to switch in.

它看起来不错,但我的目标是稍后添加混合功能,并制作一种颜色校正着色器.但首先我必须获得正确的颜色.

It looks nice but, my aim is adding blending functions later and make a kind of color correction shader. but first of all I have to get the right colors.

这是我的片段着色器 http://player.thebookofshaders.com/?log=171119111216

Here is my fragment shaderhttp://player.thebookofshaders.com/?log=171119111216

uniform vec2 u_resolution;

void main() {

  vec2 st = gl_FragCoord.xy/u_resolution.xy;

  vec3 color1 = vec3(1.9,0.55,0);
  vec3 color2 = vec3(0.226,0.000,0.615);

  float mixValue = distance(st,vec2(0,1));
  vec3 color = mix(color1,color2,mixValue);

  gl_FragColor = vec4(color,mixValue);
}

这是

先谢谢了.

推荐答案

设置颜色值时,这是一个简单的错误.设置橙色时,您将红色通道的值设置为1.9,而不是1.0.

Ther is a simple mistake when you set up the color value. You used 1.9 for the value of red color channel instead of 1.0, when you set up the orange color.

将您的代码更改为:

vec3 color1 = vec3(1.0, 0.55, 0.0); // 1.0 insted of 1.9

请注意,最终的颜色通道固定为[0,1],但是由于您使用mix插值颜色,因此高于1.0的颜色通道会增加渐变中部分颜色.

Note, the final color channels are clamped to [0, 1], but since you use mix to interpolate the colors, a color channel above 1.0 raises the part of the color in the gradient.


预览:


var ShaderProgram = {};
  ShaderProgram.Create = function( shaderList ) {
      var shaderObjs = [];
      for ( var i_sh = 0; i_sh < shaderList.length; ++ i_sh ) {
          var shderObj = this.CompileShader( shaderList[i_sh].source, shaderList[i_sh].stage );
          if ( shderObj == 0 )
              return 0;
          shaderObjs.push( shderObj );
      }
      var progObj = this.LinkProgram( shaderObjs )
      if ( progObj != 0 ) {
          progObj.attribIndex = {};
          var noOfAttributes = gl.getProgramParameter( progObj, gl.ACTIVE_ATTRIBUTES );
          for ( var i_n = 0; i_n < noOfAttributes; ++ i_n ) {
              var name = gl.getActiveAttrib( progObj, i_n ).name;
              progObj.attribIndex[name] = gl.getAttribLocation( progObj, name );
          }
          progObj.unifomLocation = {};
          var noOfUniforms = gl.getProgramParameter( progObj, gl.ACTIVE_UNIFORMS );
          for ( var i_n = 0; i_n < noOfUniforms; ++ i_n ) {
              var name = gl.getActiveUniform( progObj, i_n ).name;
              progObj.unifomLocation[name] = gl.getUniformLocation( progObj, name );
          }
      }
      return progObj;
  }
  ShaderProgram.AttributeIndex = function( progObj, name ) { return progObj.attribIndex[name]; }
  ShaderProgram.UniformLocation = function( progObj, name ) { return progObj.unifomLocation[name]; }
  ShaderProgram.Use = function( progObj ) { gl.useProgram( progObj ); }
  ShaderProgram.SetUniformF2  = function( progObj, name, arr ) { if(progObj.unifomLocation[name]) gl.uniform2fv( progObj.unifomLocation[name], arr ); }
  ShaderProgram.CompileShader = function( source, shaderStage ) {
      var shaderScript = document.getElementById(source);
      if (shaderScript) {
        source = "";
        var node = shaderScript.firstChild;
        while (node) {
          if (node.nodeType == 3) source += node.textContent;
          node = node.nextSibling;
        }
      }
      var shaderObj = gl.createShader( shaderStage );
      gl.shaderSource( shaderObj, source );
      gl.compileShader( shaderObj );
      var status = gl.getShaderParameter( shaderObj, gl.COMPILE_STATUS );
      if ( !status ) alert(gl.getShaderInfoLog(shaderObj));
      return status ? shaderObj : 0;
  }
  ShaderProgram.LinkProgram = function( shaderObjs ) {
      var prog = gl.createProgram();
      for ( var i_sh = 0; i_sh < shaderObjs.length; ++ i_sh )
          gl.attachShader( prog, shaderObjs[i_sh] );
      gl.linkProgram( prog );
      status = gl.getProgramParameter( prog, gl.LINK_STATUS );
      if ( !status ) alert("Could not initialise shaders");
      gl.useProgram( null );
      return status ? prog : 0;
  }

  function drawScene(){

      var canvas = document.getElementById( "ogl-canvas" );
      var vp = [canvas.width, canvas.height];

      gl.viewport( 0, 0, canvas.width, canvas.height );
      gl.enable( gl.DEPTH_TEST );
      gl.clearColor( 0.0, 0.0, 0.0, 1.0 );
      gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
      ShaderProgram.Use( progDraw );
      ShaderProgram.SetUniformF2( progDraw, "u_resolution", vp )
      gl.enableVertexAttribArray( progDraw.inPos );
      gl.bindBuffer( gl.ARRAY_BUFFER, bufObj.pos );
      gl.vertexAttribPointer( progDraw.inPos, 2, gl.FLOAT, false, 0, 0 );
      gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, bufObj.inx );
      gl.drawElements( gl.TRIANGLES, bufObj.inx.len, gl.UNSIGNED_SHORT, 0 );
      gl.disableVertexAttribArray( progDraw.pos );
  }

  var gl;
  var prog;
  var bufObj = {};
  function sceneStart() {

      var canvas = document.getElementById( "ogl-canvas");
      gl = canvas.getContext( "experimental-webgl", { premultipliedAlpha: true } );
      if ( !gl )
        return;

      progDraw = ShaderProgram.Create(
        [ { source : "draw-shader-vs", stage : gl.VERTEX_SHADER },
          { source : "draw-shader-fs", stage : gl.FRAGMENT_SHADER }
        ] );
      progDraw.inPos = gl.getAttribLocation( progDraw, "inPos" );
      if ( prog == 0 )
          return;

      var pos = [ -1, -1, 1, -1, 1, 1, -1, 1 ];
      var inx = [ 0, 1, 2, 0, 2, 3 ];
      bufObj.pos = gl.createBuffer();
      gl.bindBuffer( gl.ARRAY_BUFFER, bufObj.pos );
      gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( pos ), gl.STATIC_DRAW );
      bufObj.inx = gl.createBuffer();
      bufObj.inx.len = inx.length;
      gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, bufObj.inx );
      gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( inx ), gl.STATIC_DRAW );

      setInterval(drawScene, 50);
  }
<script id="draw-shader-vs" type="x-shader/x-vertex">
  precision mediump float;

  attribute vec2 inPos;

  varying vec2 vertPos;

  void main()
  {
      vertPos = inPos;
      gl_Position = vec4( inPos.xy, 0.0, 1.0 );
  }
  </script>

  <script id="draw-shader-fs" type="x-shader/x-fragment">
  precision mediump float;

  varying vec2 vertPos;
  uniform vec2 u_resolution;


void main()
{
    vec2 st = gl_FragCoord.xy/u_resolution.xy;

    vec3 color1 = vec3(1.0,0.55,0);
    vec3 color2 = vec3(0.226,0.000,0.615);

    float mixValue = distance(st,vec2(0,1));

    vec3 color = mix(color1,color2,mixValue);

    gl_FragColor = vec4(color,1.0);
}
</script>

<body onload="sceneStart();">
      <canvas id="ogl-canvas" style="border: none;" width="256" height="256"></canvas>
 </body>

这篇关于在片段着色器中创建渐变颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 04:13
查看更多