2

申し訳ありませんが、私はopengl esの初心者であり、以下の処理とシェーダーは背景のみを出力します

PShader グーロー、フォン;

rocket = loadShape("rocket.obj");
rocket.setFill(color(800, 0, 0));
Gouraud= loadShader("gouraudfragment.glsl","gouraudvertex.glsl");
Phong= loadShader("phongfragment.glsl","phongvertex.glsl");
background(0);

pushMatrix();
shader(Gouraud);
translate(130,height/2.0);
rotateY(rc);
rotateX(0.4);
noStroke();
fill(#800080);
box(100);

rc+=(0.02+speedCube);
rc*=dirCube;
popMatrix();

pushMatrix();
shader(Gouraud);
translate(width/2, height/2 + 100, -200);
rotateZ(PI);
rotateY(rr);
shape(rocket,100,100);

rr +=( 0.02+speedRocket);
rr*=dirRocket;
popMatrix();

頂点シェーダー

varying vec3 N;
varying vec3 v;
varying vec4 diffuse;
varying vec4 spec;
attribute vec4 position;
attribute vec3 normal;
uniform mat4 modelview;
uniform mat4 projectionMatrix;
uniform mat3 normalMatrix;
uniform vec4 lightPosition;
uniform vec3 lightAmbient;
uniform vec3 lightDiffuse;
uniform vec3 lightSpecular;
uniform float SpecularPower;

void main()
{
   vec4 diffuse;
   vec4 spec;
   vec4 ambient;

   v = vec3(modelview * position);
   N = normalize(normalMatrix * normal);
   gl_Position = projectionMatrix * position;  

   vec3 L = normalize(lightPosition.xyz - v);
   vec3 E = normalize(-v);
   vec3 R = normalize(reflect(-L,N)); 

   ambient = vec4(lightAmbient,100.0);
   diffuse = vec4(clamp( lightDiffuse * max(dot(N,L), 0.0)  , 0.0, 1.0 ) ,100.0);
   spec = vec4(clamp (lightSpecular * pow(max(dot(R,E),0.0),0.3*SpecularPower) , 0.0, 1.0 ),100.0);

   color = ambient + diffuse + spec;
}

フラグメントシェーダー

void main()
{
    gl_FragColor = color;
}

助けてください!グーローシェーディング適用前 ここに画像の説明を入力

グーローシェーディング適用後 グーローの後

処理はobjを読み込んで立方体を描画し、グーローシェーダーを適用しますが、その後は背景のみが表示され、objが読み込まれ、立方体はなくなります。何も表示されません!

4

1 に答える 1

1

シェーダーはコンパイルもリンクもしません。頂点シェーダーには 1 つのvarying出力 ( color) があるため、framgent シェーダーには入力が必要varying vec4 color;です。

varying vec4 color;

クリップ スペースの位置を設定すると、モデル ビューと射影行列によって頂点座標を変換する必要があります。

gl_Position = projectionMatrix * modelview * position; 

vとの型指定Nが欠落しており、 、 と の型は でambientdiffuseありspecませvec4vec3

頂点シェーダー:

attribute vec4 position;
attribute vec3 normal;

varying vec4 color;

uniform mat4 modelview;
uniform mat4 projectionMatrix;
uniform mat3 normalMatrix;
uniform vec4 lightPosition;
uniform vec3 lightAmbient;
uniform vec3 lightDiffuse;
uniform vec3 lightSpecular;
uniform float SpecularPower;

void main()
{
   vec3 v      = vec3(modelview * position);
   vec3 N      = normalize(normalMatrix * normal);
   gl_Position = projectionMatrix * modelview * position;  

   vec3 L = normalize(lightPosition.xyz - v);
   vec3 E = normalize(-v);
   vec3 R = normalize(reflect(-L,N)); 

   vec4 ambient = vec4(lightAmbient,100.0);
   vec4 diffuse = vec4(clamp( lightDiffuse * max(dot(N,L), 0.0)  , 0.0, 1.0 ) ,100.0);
   vec4 spec = vec4(clamp (lightSpecular * pow(max(dot(R,E),0.0),0.3*SpecularPower) , 0.0, 1.0 ),100.0);

   color = ambient + diffuse + spec;
}

フラグメント シェーダー:

varying vec4 color;

void main()
{
    gl_FragColor = color;
}

もちろん、少なくとも環境光源を設定する必要がありますambientLight()directionalLight()pointLight()またはも使用できますspotLight()
ただし、シェーダーは 1 つの光源しか処理できないことに注意してください。より多くの 1 つの光源が得られます

上部 endDraw() の OpenGL エラー 1282: 無効な操作

複数の光源を使用する場合は、 、 、 、および の頂点シェーダーで均一な配列を使用する必要lightPositionlightAmbientありlightDiffuseますlightSpecularProcessing のシェーダーのタイプを参照してください( https://processing.org/tutorials/pshader/ )

于 2020-01-23T17:40:47.467 に答える