在 webgl 中调试 GLSL 代码

问题描述 投票:0回答:3

与 webgl 一起使用时是否可以调试 GLSL 代码或打印 glsl 代码中的变量值? Three.js 或 scene.js 是否包含此类功能?

javascript three.js glsl webgl
3个回答
20
投票

其实不然,

我通常调试GLSL的方式是输出颜色。例如,给定 2 个着色器,例如

// vertex shader
uniform mat4 worldViewProjection;
uniform vec3 lightWorldPos;
uniform mat4 world;
uniform mat4 viewInverse;
uniform mat4 worldInverseTranspose;
attribute vec4 position;
attribute vec3 normal;
attribute vec2 texCoord;
varying vec4 v_position;
varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec3 v_surfaceToLight;
varying vec3 v_surfaceToView;
void main() {
  v_texCoord = texCoord;
  v_position = (worldViewProjection * position);
  v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz;
  v_surfaceToLight = lightWorldPos - (world * position).xyz;
  v_surfaceToView = (viewInverse[3] - (world * position)).xyz;
  gl_Position = v_position;
}

// fragment-shader    
precision highp float;

uniform vec4 colorMult;
varying vec4 v_position;
varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec3 v_surfaceToLight;
varying vec3 v_surfaceToView;

uniform sampler2D diffuseSampler;
uniform vec4 specular;
uniform sampler2D bumpSampler;
uniform float shininess;
uniform float specularFactor;

vec4 lit(float l ,float h, float m) {
  return vec4(1.0,
              max(l, 0.0),
              (l > 0.0) ? pow(max(0.0, h), m) : 0.0,
              1.0);
}
void main() {
  vec4 diffuse = texture2D(diffuseSampler, v_texCoord) * colorMult;
  vec3 normal = normalize(v_normal);
  vec3 surfaceToLight = normalize(v_surfaceToLight);
  vec3 surfaceToView = normalize(v_surfaceToView);
  vec3 halfVector = normalize(surfaceToLight + surfaceToView);
  vec4 litR = lit(dot(normal, surfaceToLight),
                    dot(normal, halfVector), shininess);
  gl_FragColor = vec4((
  vec4(1,1,1,1) * (diffuse * litR.y
                        + specular * litR.z * specularFactor)).rgb,
      diffuse.a);
}

如果我在屏幕上没有看到任何内容,我会首先通过在末尾添加一行来更改片段着色器

gl_FragColor = vec4(1,0,0,1);  // draw red

如果我开始看到我的几何体,那么我就会知道问题可能出在片段着色器中。我可以通过这样做来检查我的正常情况

gl_FragColor = vec4(v_normal * 0.5 + 0.5, 1);

如果法线看起来不错,我可能会检查 UV 坐标

gl_FragColor = vec4(v_texCoord, 0, 1);

等等...


0
投票

有一个老项目,将shaders编译成JS进行调试: https://github.com/burg/glsl-simulator

我正在制作一个 TypeScript 版本,除了编译 GLSL 之外,还向 TypeScript 添加了运算符重载和混合: https://github.com/nelipuu/glslog

很容易在以下位置进行测试: https://codepen.io/Juha-J-rvi/pen/YzooeGJ

因此您可以在着色器中包含 TypeScript 代码,例如:

#ifdef TS
  print('Hello, World!', abs(pos.xy) + 1);
#endif

-2
投票

您可以尝试使用 WebGL-Inspector 来实现此目的。

© www.soinside.com 2019 - 2024. All rights reserved.