eliemichel / LearnWebGPU-Code

The accompanying code of the Learn WebGPU C++ programming guide
https://eliemichel.github.io/LearnWebGPU
MIT License
90 stars 23 forks source link

issue with step125? #4

Closed meshula closed 1 year ago

meshula commented 1 year ago

Hi! On a windows machine I'm getting the failure below on step125. Before digging in, I thought I would check if step 125 is ready. If it's still in progress, I can ignore this problem for now. I haven't tried to chase down why that MaxBuffSize error comes up.

Requesting adapter...
Got adapter: <wgpu::Adapter 000002226A03AA90>
Requesting device...
Got device: <wgpu::Device 0000022269FD7AB0>
Creating swapchain...
Swapchain: <wgpu::SwapChain 0000022268EDD2F0>
Creating shader module...
Device error: type 4 (message: Validation(ShaderError { source: "const PI = 3.14159265359;\n\n/* **************** SHADING **************** */\n\n/**\n * Standard properties of a material\n * (Describe all the properties of a surface needed to shade it)\n */\nstruct MaterialProperties {\n\tbaseColor: vec3<f32>,\n\troughness: f32,\n\tmetallic: f32,\n\treflectance: f32,\n\thighQuality: u32, // bool, turn on costly extra visual effects\n}\n\n/**\n * Given some material properties, the BRDF (Bidirectional Reflection\n * Distribution Function) tells the probability that a photon coming from an\n * incoming direction (towards the light) is reflected in an outgoing direction\n * (towards the camera).\n * The returned value gives a different probability for each color channel.\n */\nfn brdf(\n\tmaterial: MaterialProperties,\n\tnormal: vec3<f32>, // assumed to be normalized\n\tincomingDirection: vec3<f32>, // assumed to be normalized\n\toutgoingDirection: vec3<f32>, // assumed to be normalized\n) -> vec3<f32> {\n\t// Switch to compact notations used in math formulas\n\t// (notations of https://google.github.io/filament/Filament.html)\n\tlet L = incomingDirection;\n\tlet V = outgoingDirection;\n\tlet N = normal;\n\tlet H = normalize(L + V);\n\tlet alpha = material.roughness * material.roughness;\n\n\tlet NoV = abs(dot(N, V)) + 1e-5;\n\tlet NoL = clamp(dot(N, L), 0.0, 1.0);\n\tlet NoH = clamp(dot(N, H), 0.0, 1.0);\n\tlet LoH = clamp(dot(L, H), 0.0, 1.0);\n\n\t// == Specular (reflected) lobe ==\n\t// Contribution of the Normal Distribution Function (NDF)\n\tlet D = D_GGX(NoH, alpha);\n\t// Self-shadowing\n\tlet Vis = V_SmithGGXCorrelatedFast(NoV, NoL, alpha);\n\t// Fresnel\n\tlet f0_dielectric = vec3<f32>(0.16 * material.reflectance * material.reflectance);\n\tlet f0_conductor = material.baseColor;\n\tlet f0 = mix(f0_dielectric, f0_conductor, material.metallic);\n\tlet F = F_Schlick_vec3f(LoH, f0, 1.0);\n\tlet f_r = D * Vis * F;\n\n\t// == Diffuse lobe ==\n\tlet diffuseColor = (1.0 - material.metallic) * material.baseColor;\n\tvar f_d = vec3<f32>(0.0);\n\tif (material.highQuality != 0) {\n\t\tf_d = diffuseColor * Fd_Burley(NoV, NoL, LoH, alpha);\n\t} else {\n\t\tf_d = diffuseColor * Fd_Lambert();\n\t}\n\n\treturn f_r + f_d;\n}\n\nfn D_GGX(NoH: f32, roughness: f32) -> f32 {\n\tlet a = NoH * roughness;\n\tlet k = roughness / (1.0 - NoH * NoH + a * a);\n\treturn k * k * (1.0 / PI);\n}\n\nfn V_SmithGGXCorrelatedFast(NoV: f32, NoL: f32, roughness: f32) -> f32 {\n\tlet a = roughness;\n\tlet GGXV = NoL * (NoV * (1.0 - a) + a);\n\tlet GGXL = NoV * (NoL * (1.0 - a) + a);\n\treturn clamp(0.5 / (GGXV + GGXL), 0.0, 1.0);\n}\n\n// f90 is 1.0 for specular\nfn F_Schlick_vec3f(u: f32, f0: vec3<f32>, f90: f32) -> vec3<f32> {\n\tlet v_pow_1 = 1.0 - u;\n\tlet v_pow_2 = v_pow_1 * v_pow_1;\n\tlet v_pow_5 = v_pow_2 * v_pow_2 * v_pow_1;\n\treturn f0 * (1.0 - v_pow_5) + vec3<f32>(f90) * v_pow_5;\n}\nfn F_Schlick_f32(u: f32, f0: f32, f90: f32) -> f32 {\n\tlet v_pow_1 = 1.0 - u;\n\tlet v_pow_2 = v_pow_1 * v_pow_1;\n\tlet v_pow_5 = v_pow_2 * v_pow_2 * v_pow_1;\n\treturn f0 * (1.0 - v_pow_5) + f90 * v_pow_5;\n}\n\nfn Fd_Lambert() -> f32 {\n    return 1.0 / PI;\n}\n\n// More costly but more realistic at grazing angles\nfn Fd_Burley(NoV: f32, NoL: f32, LoH: f32, roughness: f32) -> f32 {\n    let f90 = 0.5 + 2.0 * roughness * LoH * LoH;\n    let lightScatter = F_Schlick_f32(NoL, 1.0, f90);\n    let viewScatter = F_Schlick_f32(NoV, 1.0, f90);\n    return lightScatter * viewScatter / PI;\n}\n\n/**\n * Sample a local normal from the normal map and rotate it using the normal\n * frame to get a global normal.\n */\nfn sampleNormal(in: VertexOutput, normalMapStrength: f32) -> vec3<f32> {\n\tlet encodedN = textureSample(normalTexture, textureSampler, in.uv).rgb;\n\tlet localN = encodedN - 0.5;\n\tlet rotation = mat3x3<f32>(\n\t\tnormalize(in.tangent),\n\t\tnormalize(in.bitangent),\n\t\tnormalize(in.normal),\n\t);\n\tlet rotatedN = normalize(rotation * localN);\n\treturn normalize(mix(in.normal, rotatedN, normalMapStrength));\n}\n\n/* **************** BINDINGS **************** */\n\nstruct VertexInput {\n\t@builtin(instance_index) instance_index: u32,\n\t@location(0) position: vec3<f32>,\n\t@location(4) tangent: vec3<f32>,\n\t@location(5) bitangent: vec3<f32>,\n\t@location(1) normal: vec3<f32>,\n\t@location(2) color: vec3<f32>,\n\t@location(3) uv: vec2<f32>,\n}\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4<f32>,\n\t@location(0) color: vec3<f32>,\n\t@location(4) tangent: vec3<f32>,\n\t@location(5) bitangent: vec3<f32>,\n\t@location(1) normal: vec3<f32>,\n\t@location(2) uv: vec2<f32>,\n\t@location(3) viewDirection: vec3<f32>,\n\t@location(6) instance: f32,\n}\n\n/**\n * A structure holding the value of our uniforms\n */\nstruct MyUniforms {\n\tprojectionMatrix: mat4x4<f32>,\n\tviewMatrix: mat4x4<f32>,\n\tmodelMatrix: mat4x4<f32>,\n\tcolor: vec4<f32>,\n\tcameraWorldPosition: vec3<f32>,\n\ttime: f32,\n\tgamma: f32,\n}\n\n/**\n * A structure holding the lighting settings\n */\nstruct LightingUniforms {\n\tdirections: array<vec4<f32>, 2>,\n\tcolors: array<vec4<f32>, 2>,\n\troughness: f32,\n\tmetallic: f32,\n\treflectance: f32,\n\tnormalMapStrength: f32,\n\thighQuality: u32,\n\troughness2: f32,\n\tmetallic2: f32,\n\treflectance2: f32,\n\tinstanceSpacing: f32,\n}\n\n// Instead of the simple uTime variable, our uniform variable is a struct\n@group(0) @binding(0) var<uniform> uMyUniforms: MyUniforms;\n@group(0) @binding(5) var<uniform> uLighting: LightingUniforms;\n\n@group(0) @binding(1) var textureSampler: sampler;\n@group(0) @binding(2) var baseColorTexture: texture_2d<f32>;\n@group(0) @binding(3) var normalTexture: texture_2d<f32>;\n@group(0) @binding(4) var environmentTexture: texture_2d<f32>;\n\n/* **************** VERTEX MAIN **************** */\n\n@vertex\nfn vs_main(in: VertexInput) -> VertexOutput {\n\tvar out: VertexOutput;\n\tlet worldPosition = uMyUniforms.modelMatrix * vec4<f32>(in.position, 1.0);\n\tout.instance = f32(in.instance_index) / 8.0;\n\t\n\t// A trick to offset instances without changing their perspective\n\tvar proj = uMyUniforms.projectionMatrix;\n\tproj[2][0] = (out.instance - 0.5) * uLighting.instanceSpacing;\n\n\tout.position = proj * uMyUniforms.viewMatrix * worldPosition;\n\tout.color = in.color;\n\tout.tangent = (uMyUniforms.modelMatrix * vec4<f32>(in.tangent, 0.0)).xyz;\n\tout.bitangent = (uMyUniforms.modelMatrix * vec4<f32>(in.bitangent, 0.0)).xyz;\n\tout.normal = (uMyUniforms.modelMatrix * vec4<f32>(in.normal, 0.0)).xyz;\n\tout.uv = in.uv;\n\tout.viewDirection = uMyUniforms.cameraWorldPosition - worldPosition.xyz;\n\treturn out;\n}\n\n/* **************** FRAGMENT MAIN **************** */\n\n@fragment\nfn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {\n\tlet N = sampleNormal(in, uLighting.normalMapStrength);\n\n\t// Compute shading\n\tlet V = normalize(in.viewDirection);\n\n\t/*\n\t// Instead of looping over the light sources, we sample the environment map\n\t// in the reflected direction to get the specular shading.\n\tlet ibl_direction = -reflect(V, N);\n\tlet Pi = 3.14159266;\n\tlet theta = acos(ibl_direction.z / length(ibl_direction));\n\tlet phi = atan2(length(ibl_direction.xy), ibl_direction.x);\n\tlet ibl_uv = vec2<f32>(phi / (2.0 * Pi), theta / Pi + 0.5);\n\tlet ibl_sample = textureSample(environmentTexture, textureSampler, ibl_uv).rgb;\n\n\tvar diffuse = vec3<f32>(0.0);\n\tlet specular = ibl_sample;\n\t*/\n\t\n\t// Sample texture\n\tlet baseColor = textureSample(baseColorTexture, textureSampler, in.uv).rgb;\n\n\t// Combine texture and lighting\n\t//let color = baseColor * uLighting.kd * diffuse + uLighting.ks * specular;\n\n\t// To debug normals\n\t//let color = N * 0.5 + 0.5;\n\n\tlet material = MaterialProperties(\n\t\tbaseColor,\n\t\tmix(uLighting.roughness, uLighting.roughness2, in.instance),\n\t\tmix(uLighting.metallic, uLighting.metallic2, in.instance),\n\t\tmix(uLighting.reflectance, uLighting.reflectance2, in.instance),\n\t\tuLighting.highQuality,\n\t);\n\tvar color = vec3<f32>(0.0);\n\tfor (var i: i32 = 0; i < 2; i++) {\n\t\tlet L = normalize(uLighting.directions[i].xyz);\n\t\tlet lightEnergy = uLighting.colors[i].rgb * 2.0;\n\t\tcolor += brdf(material, N, L, V) * lightEnergy;\n\t}\n\n\t// Gamma-correction\n\tlet corrected_color = pow(color, vec3<f32>(uMyUniforms.gamma));\n\treturn vec4<f32>(corrected_color, uMyUniforms.color.a);\n}\n", label: None, inner: WithSpan { inner: Function { handle: [7], name: "brdf", source: Expression { handle: [51], source: InvalidBinaryOperandTypes(NotEqual, [49], [50]) } }, spans: [(Span { start: 692, end: 2080 }, "naga::Function [7]"), (Span { start: 1926, end: 1951 }, "naga::Expression [51]")] } }))
Shader module: <wgpu::ShaderModule 0000000000000000>
Device error: type 4 (message: MaxBufferSize { requested: 10199184, maximum: 4194304 })
thread '<unnamed>' panicked at 'invalid BufferId', src\lib.rs:220:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
eliemichel commented 1 year ago

Hello!

The redaction of the chapter is still WIP, but the code should work. I had tested it more with Dawn lately, so some minor fixes were still here with wgpu-native (which is a bit more strict on device limits and shader typing).

So I just updated the branch, and I also updated WebGPU-distribution because there was a new release of wgpu-native yesterday, you should update your fetched repo by doing the following:

cd build\_deps\webgpu-backend-wgpu-src
git pull
meshula commented 1 year ago

Thanks, it runs now :)