1

我正在用 C# 和 OpenTK 编写关卡编辑器,并想看看更复杂的着色器是否可以正常工作。所以我在这里抓住了这个我的工艺着色器https://www.shadertoy.com/view/MdlGz4

但我无法让它工作,我不断收到这个错误:

Failed to link shader program!
Fragment info
-------------
Internal error: assembly compile error for fragment shader at offset 392911:
-- error message --
line 16405, column 1:  error: too many instructions
-- internal assembly text --
!!NVfp5.0
OPTION NV_bindless_texture;
OPTION NV_shader_atomic_float;
# cgc version 3.1.0001, build date Feb  9 2013
# command line args: 
#vendor NVIDIA Corporation
#version 3.1.0.1
#profile gp5fp

shadertoy 版本在我的浏览器中运行良好。所以我知道我的硬件(GTX 680)可以处理它。我在片段着色器中使用#version 400,希望更高版本允许更多指令。但这也无济于事。所以我的问题是,我如何加载/编译这么长的片段着色器?

这是我正在尝试运行的实际着色器:

顶点:

#version 400

uniform mat4 camera;
uniform mat4 model;
in vec3 in_vertex;
in vec4 in_color;
in vec2 in_uv;
out vec2 frag_TexCoord;
out vec4 frag_Color;

void main()
{
    gl_Position = camera * model * vec4(in_vertex, 1);
    frag_TexCoord = in_uv;
    frag_Color = in_color;
}

分段:

#version 400

uniform vec2 iResolution;
uniform float iGlobalTime;
in vec4 frag_Color;
in vec2 frag_TexCoord;
out vec4 final_color;

// Created by Reinder Nijhoff 2013
//
// port of javascript minecraft: http://jsfiddle.net/uzMPU/
// original code by Markus Persson: https://twitter.com/notch/status/275331530040160256

float hash( float n ) {
    return fract(sin(n)*43758.5453);
}

// port of minecraft

bool getMaterialColor( int i, vec2 coord, out vec3 color ) {
    // 16x16 tex
    vec2 uv = floor( coord );

    float n = uv.x + uv.y*347.0 + 4321.0 * float(i);
    float h = hash(n);

    float br = 1. - h * (96./255.
                        );
    color = vec3( 150./255., 108./255.,  74./255.); // 0x966C4A;

    if (i == 4) {
        color = vec3( 127./255., 127./255., 127./255.); // 0x7F7F7F;
    }

    float xm1 = mod((uv.x * uv.x * 3. + uv.x * 81.) / 4., 4.);

    if (i == 1) {
        if( uv.y < (xm1 + 18.)) {
            color = vec3( 106./255., 170./255.,  64./255.); // 0x6AAA40;
        } else if (uv.y < (xm1 + 19.)) {
            br = br * (2. / 3.);
        }
    }

    if (i == 7) {
        color = vec3( 103./255., 82./255.,  49./255.); // 0x675231;
        if (uv.x > 0. && uv.x < 15.
            && ((uv.y > 0. && uv.y < 15.) || (uv.y > 32. && uv.y < 47.))) {
            color = vec3( 188./255., 152./255.,  98./255.); // 0xBC9862;
            float xd = (uv.x - 7.);
            float yd = (mod(uv.y, 16.) - 7.);
            if (xd < 0.)
                xd = 1. - xd;
            if (yd < 0.)
                yd = 1. - yd;
            if (yd > xd)
                xd = yd;

            br = 1. - (h * (32./255.) + mod(xd, 4.) * (32./255.));
        } else if ( h < 0.5 ) {
            br = br * (1.5 - mod(uv.x, 2.));
        }
    }

    if (i == 5) {
        color = vec3( 181./255.,  58./255.,  21./255.); // 0xB53A15;
        if ( mod(uv.x + (floor(uv.y / 4.) * 5.), 8.) == 0. || mod( uv.y, 4.) == 0.) {
            color = vec3( 188./255., 175./255., 165./255.); // 0xBCAFA5;
        }
    }
    if (i == 9) {
        color = vec3(  64./255.,  64./255., 255./255.); // 0x4040ff;
    }

    float brr = br;
    if (uv.y >= 32.)
        brr /= 2.;

    if (i == 8) {
        color = vec3(  80./255., 217./255.,  55./255.); // 0x50D937;
        if ( h < 0.5) {
            return false;
        }
    }

    color *= brr;

    return true;
}

int getMap( vec3 pos ) {    
    vec3 posf = floor( (pos - vec3(32.))  );

    float n = posf.x + posf.y*517.0 + 1313.0*posf.z;
    float h = hash(n);

    if( h > sqrt( sqrt( dot( posf.yz, posf.yz )*0.16 ) ) - 0.8  ) {
        return 0;
    }   

    return int( hash( n * 465.233 ) * 16. );
}

vec3 renderMinecraft( vec2 uv ) {
    float xRot = sin( iGlobalTime*0.5 ) * 0.4 + (3.1415 / 2.);
    float yRot = cos( iGlobalTime*0.5 ) * 0.4;
    float yCos = cos(yRot);
    float ySin = sin(yRot);
    float xCos = cos(xRot);
    float xSin = sin(xRot);

    vec3 opos = vec3( 32.5 + iGlobalTime * 6.4, 32.5, 32.5 );

    float gggxd = (uv.x - 0.5) * (iResolution.x / iResolution.y );
    float ggyd = (1.-uv.y - 0.5);
    float ggzd = 1.;

    float gggzd = ggzd * yCos + ggyd * ySin;

    vec3 _posd = vec3( gggxd * xCos + gggzd * xSin,
                       ggyd * yCos - ggzd * ySin,
                       gggzd * xCos - gggxd * xSin );

    vec3 col = vec3( 0. );
    float br = 1.;
    vec3 bdist = vec3( 255. - 100., 255. -   0., 255. -  50.  );
    float ddist = 0.;

    float closest = 32.;

    for ( int d = 0; d < 3; d++) {
        float dimLength = _posd[d];

        float ll = abs( 1. / dimLength );
        vec3 posd = _posd * ll;;

        float initial = fract( opos[d] );
        if (dimLength > 0.) initial = 1. - initial;

        float dist = ll * initial;

        vec3 pos = opos + posd * initial;

        if (dimLength < 0.) {
            pos[d] -= 1.;
        }

        for (int i=0; i<30; i++) {
            if( dist > closest )continue;

            //int tex = getMap( mod( pos, 64. ) );
            int tex = getMap( pos );

            if (tex > 0) {
                vec2 texcoord;
                texcoord.x = mod(((pos.x + pos.z) * 16.), 16.);
                texcoord.y = mod((pos.y * 16.), 16.) + 16.;
                if (d == 1) {
                    texcoord.x = mod(pos.x * 16., 16.);
                    texcoord.y = mod(pos.z * 16., 16.);
                    if (posd.y < 0.)
                        texcoord.y += 32.;
                }

                if ( getMaterialColor( tex, texcoord, col ) ) {
                    ddist = 1. - (dist / 32.);
                    br = bdist[d];
                    closest = dist;
                }
            }
            pos += posd;
            dist += ll;
        }
    }

    return col * ddist * (br/255.);
}

void main()
{
    vec2 uv = frag_TexCoord.xy / iResolution.xy;
    final_color = vec4( renderMinecraft( uv ) ,1.0);
}

澄清错误发生在哪里: 编译顶点和片段着色器的前两个步骤工作正常。它是返回 0 的链接 (GL.GetProgram())。对 GL.GetProgramInfo 的调用返回上述错误并以汇编代码列出程序(# 19337 指令,8 个 R-regs)。所以它确实有这么多行。

_vertexShader = GL.CreateShader(ShaderType.VertexShader);
GL.ShaderSource(_vertexShader, vertexProgram);
GL.CompileShader(_vertexShader);
GL.GetShader(_vertexShader, ShaderParameter.CompileStatus, out result);
if (result == 0)
{
    System.Diagnostics.Debug.WriteLine(GL.GetString(StringName.ShadingLanguageVersion));
    System.Diagnostics.Debug.WriteLine(GL.GetShaderInfoLog(_vertexShader));
}

//Create Fragment Shader
_fragShader = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(_fragShader, fragmentProgram);
GL.CompileShader(_fragShader);
GL.GetShader(_fragShader, ShaderParameter.CompileStatus, out result);
if (result == 0)
{
    System.Diagnostics.Debug.WriteLine(GL.GetString(StringName.ShadingLanguageVersion));
    System.Diagnostics.Debug.WriteLine(GL.GetShaderInfoLog(_fragShader));
}

//Link to program
_shader = GL.CreateProgram();
GL.AttachShader(_shader, _vertexShader);
GL.AttachShader(_shader, _fragShader);
GL.LinkProgram(_shader);
GL.GetProgram(_shader, ProgramParameter.LinkStatus, out result);
if (result == 0)
{
    System.Diagnostics.Debug.WriteLine("Failed to link shader program!");
    System.Diagnostics.Debug.WriteLine(GL.GetProgramInfoLog(_shader));
    GL.DeleteProgram(_shader);
}
4

0 回答 0