asny / three-d

2D/3D renderer - makes it simple to draw stuff across platforms (including web)
MIT License
1.24k stars 105 forks source link

Trying to use PhysicalMaterial without lights crashes the program #454

Open cwitty opened 2 months ago

cwitty commented 2 months ago

I was trying to get some three_d code to work by copying and pasting different bits of your examples together (employing the rightfully disdained "cargo cult programming"). In the process I copied some code using PhysicalMaterial from the shapes demo into a rendering main loop that's mostly based on the screen demo, and my code started crashing with this error message:

the attribute normal is sent to the shader but not defined or never used

(from src/core/program.rs:621)

It took me a while of debugging, but stepping through, I can see that the vertex shader defines USE_NORMALS and looks correct; but my code (based on the screen demo) never adds any lights, which means that the fragment shader output doesn't actually depend on the "nor" input, which I think means the driver decided that there's no point in computing "nor" or reading "normal" in the vertex shader. And indeed, the compiled vertex shader only reads one attribute, "position".

I'm not sure if there's anything you want to fix; after all, the problem was arguably my fault. But how about adding something like this in physical_material.rs:fragment_shader_source() (untested):

if lights.is_empty() { panic!("PhysicalMaterial does not work with no lights defined"); }

asny commented 1 month ago

Thanks for reporting. I guess you're on Linux? The Linux shader compiler is a bit more aggressive than on other platforms and since I'm not using Linux it's hard for me to test.

It is actually an easy fix, we should just not send normal attribute when there's no lights. The easy solution would be to use Program:: requires_attribute to check whether the normal attribute is required before sending it. If you can do a PR with that change, I'll be happy to merge it.