3D accelerators, to a large extent, changed what we (game developers) needed to focus on. If I'm doing a software rasterization of a bunch of triangles, then the speed at which I sit in that tight loop rendering each pixel is of utmost importance. Getting a texture mapping routine down to 9 clock cycles matters. The moment I worked on a game that used 3d accelerators, that all changed. I submit a list of triangles to the 3D accelerator, and it draws them. It rarely matters how much time I spend getting everything ready for the 3D accelerator, since it is rendering while I am processing, and my processing for all intents and purposes never takes longer than the rendering.
Once we had that architectural paradigm shift, the clock cycles it takes for me to prepare the drawing list are entirely irrelevant. The entire burden of performance is in getting the 3d accelerator to draw faster. This means that optimization is in reducing the work it has to do, either through fancy shading tricks to simplify what it takes to make something look right, or reducing the amount of geometry I send to the 3d accelerator to draw.
The neat thing is that we've gone full circle in a way. When it used to be important to hand optimize the inner loop of a rasterisation function, now we have pixel, vertex, and fragment shaders. The pixel and fragment shaders are getting run millions of times, and we used to have to code shaders in shader assembly. Now they're generally written in higher level shading language, but nonetheless, optimizing shader code often becomes quite important. It feels like the same work as assembly optimization to me.