我想尝试程序 3D 引擎。代码是正确的,只有我得到:
“GLSL 编译失败
片段_着色器
================
错误:0:727:'pMod1':找不到匹配的重载函数(使用隐式转换)
错误:0:727:'pMod1':函数未知“
此代码连接到hg_sdf.glsl。但由于某种原因,尽管其他的工作正常,但这个不起作用。没有它一切都正常。
这是代码:
”
#version 330 core
#include hg_sdf.glsl
layout (location = 0) out vec4 fragColor;
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
const float FOV = 1.0;
const int MAX_STEPS = 256;
const float MAX_DIST = 500;
const float EPSILON = 0.001;
float fDisplace(vec3 p) {
pR(p.yz, sin(2.0 * u_time));
return (sin(p.x + 4.0 * u_time) * sin(p.y + sin(2.0 * u_time)) * sin(p.z + 6.0 * u_time));
}
vec2 fOpUnionID(vec2 res1, vec2 res2) {
return (res1.x < res2.x) ? res1 : res2;
}
vec2 fOpDifferenceID(vec2 res1, vec2 res2) {
return (res1.x > -res2.x) ? res1 : vec2(-res2.x, res2.y);
}
vec2 fOpDifferenceColumnsID(vec2 res1, vec2 res2, float r, float n) {
float dist = fOpDifferenceColumns(res1.x, res2.x, r, n);
return (res1.x > -res2.x) ? vec2(dist, res1.y) : vec2(dist, res2.y);
}
vec2 fOpUnionStairsID(vec2 res1, vec2 res2, float r, float n) {
float dist = fOpUnionStairs(res1.x, res2.x, r, n);
return (res1.x < res2.x) ? vec2(dist, res1.y) : vec2(dist, res2.y);
}
vec2 fOpUnionChamferID(vec2 res1, vec2 res2, float r) {
float dist = fOpUnionChamfer(res1.x, res2.x, r);
return (res1.x < res2.x) ? vec2(dist, res1.y) : vec2(dist, res2.y);
}
vec2 map(vec3 p) {
// plane
float planeDist = fPlane(p, vec3(0, 1, 0), 14.0);
float planeID = 2.0;
vec2 plane = vec2(planeDist, planeID);
// torus
vec3 pt = p + 0.2;
pt.y -= 8;
pR(pt.yx, 4.0 * u_time);
pR(pt.yz, 0.3 * u_time);
float torusDist = fTorus(pt, 0.7, 16.0);
float torusID = 5.0;
vec2 torus = vec2(torusDist, torusID);
// sphere
vec3 ps = p + 0.2;
ps.y -= 8;
float sphereDist = fSphere(ps, 13.0 + fDisplace(p));
float sphereID = 1.0;
vec2 sphere = vec2(sphereDist, sphereID);
// manipulation operators
pMirrorOctant(p.xz, vec2(50, 50));
p.x = -abs(p.x) + 20;
pMod1(p.z, 15); #This is what causes the error
// roof
vec3 pr = p;
pr.y -= 15.7;
pR(pr.xy, 0.6);
pr.x -= 18.0;
float roofDist = fBox2Cheap(pr.xy, vec2(20, 0.5));
float roofID = 4.0;
vec2 roof = vec2(roofDist, roofID);
// box
float boxDist = fBoxCheap(p, vec3(3,9,4));
float boxID = 3.0;
vec2 box = vec2(boxDist, boxID);
// cylinder
vec3 pc = p;
pc.y -= 9.0;
float cylinderDist = fCylinder(pc.yxz, 4, 3);
float cylinderID = 3.0;
vec2 cylinder = vec2(cylinderDist, cylinderID);
// wall
float wallDist = fBox2Cheap(p.xy, vec2(1, 15));
float wallID = 3.0;
vec2 wall = vec2(wallDist, wallID);
// result
vec2 res;
// res = wall;
res = fOpUnionID(box, cylinder);
res = fOpDifferenceColumnsID(wall, res, 0.6, 3.0);
res = fOpUnionChamferID(res, roof, 0.6);
res = fOpUnionStairsID(res, plane, 4.0, 5.0);
res = fOpUnionID(res, sphere);
res = fOpUnionID(res, torus);
return res;
}
vec2 rayMarch(vec3 ro, vec3 rd) {
vec2 hit, object;
for (int i = 0; i < MAX_STEPS; i++) {
vec3 p = ro + object.x * rd;
hit = map(p);
object.x += hit.x;
object.y = hit.y;
if (abs(hit.x) < EPSILON || object.x > MAX_DIST) break;
}
return object;
}
vec3 getNormal(vec3 p) {
vec2 e = vec2(EPSILON, 0.0);
vec3 n = vec3(map(p).x) - vec3(map(p - e.xyy).x, map(p - e.yxy).x, map(p - e.yyx).x);
return normalize(n);
}
vec3 getLight(vec3 p, vec3 rd, vec3 color) {
vec3 lightPos = vec3(10.0, 55.0, -20.0);
vec3 L = normalize(lightPos - p);
vec3 N = getNormal(p);
vec3 V = -rd;
vec3 R = reflect(-L, N);
vec3 specColor = vec3(0.5);
vec3 specular = specColor * pow(clamp(dot(R, V), 0.0, 1.0), 10.0);
vec3 diffuse = color * clamp(dot(L, N), 0.0, 1.0);
vec3 ambient = color * 0.05;
vec3 fresnel = 0.25 * color * pow(1.0 + dot(rd, N), 3.0);
// shadows
float d = rayMarch(p + N * 0.02, normalize(lightPos)).x;
if (d < length(lightPos - p)) return ambient + fresnel;
return diffuse + ambient + specular + fresnel;
}
vec3 getMaterial(vec3 p, float id) {
vec3 m;
switch (int(id)) {
case 1:
m = vec3(0.9, 0.0, 0.0); break;
case 2:
m = vec3(0.2 + 0.4 * mod(floor(p.x) + floor(p.z), 2.0)); break;
case 3:
m = vec3(0.7, 0.8, 0.9); break;
case 4:
vec2 i = step(fract(0.5 * p.xz), vec2(1.0 / 10.0));
m = ((1.0 - i.x) * (1.0 - i.y)) * vec3(0.37, 0.12, 0.0); break;
}
return m;
}
mat3 getCam(vec3 ro, vec3 lookAt) {
vec3 camF = normalize(vec3(lookAt - ro));
vec3 camR = normalize(cross(vec3(0, 1, 0), camF));
vec3 camU = cross(camF, camR);
return mat3(camR, camU, camF);
}
void mouseControl(inout vec3 ro) {
vec2 m = u_mouse / u_resolution;
pR(ro.yz, m.y * PI * 0.4 - 0.4);
pR(ro.xz, m.x * TAU);
}
void render(inout vec3 col, in vec2 uv) {
vec3 ro = vec3(36.0, 19.0, -36.0);
mouseControl(ro);
vec3 lookAt = vec3(0, 1, 0);
vec3 rd = getCam(ro, lookAt) * normalize(vec3(uv, FOV));
vec2 object = rayMarch(ro, rd);
vec3 background = vec3(0.5, 0.8, 0.9);
if (object.x < MAX_DIST) {
vec3 p = ro + object.x * rd;
vec3 material = getMaterial(p, object.y);
col += getLight(p, rd, material);
// fog
col = mix(col, background, 1.0 - exp(-0.00002 * object.x * object.x));
} else {
col += background - max(0.9 * rd.y, 0.0);
}
}
void main() {
vec2 uv = (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.y;
vec3 col;
render(col, uv);
// gamma correction
col = pow(col, vec3(0.4545));
fragColor = vec4(col, 1.0);
}"
But it seems to me that this is the way to use it, since it is done more better.
我在尝试这个演示时遇到了同样的问题。
答案是 pMod1 函数期望两个参数都是浮点数,但是“15”隐含地是一个 int。不存在将 float 作为第一个参数、将 int 作为第二个参数的 pMod1 函数。
解决方案是将“15”更改为“15”。所以 const 隐式地是一个浮点数。