pvr: support shading instructions #35

Closed
inolen opened this Issue Dec 6, 2016 · 6 comments

Projects

None yet

2 participants

@inolen
Owner
inolen commented Dec 6, 2016 edited

The Dreamcast's PowerVR chip supports 4 "shading instructions" which define how the final fragment RGBA value is calculated for a given surface.

The modes are:

Setting Mode Formula
0 decal frag.rgb = tex.rgb + offset.rgb, frag.a = tex.a
1 modulate frag.rgb = tex.rgb * col.rgb + offset.rgb, frag.a = tex.a
2 decal alpha frag.rgb = (tex.rgb * tex.a) + (col.rgb * (1 - tex.a)) + offset.rgb, frag.a = col.a
3 modulate alpha frag.rgb = tex.rgb * col.rgb + offset.rgb, frag.a = tex.a * col.a

In these formulas, frag is the final fragment color, tex is the texture being sampled, and col / offset are vertex color values.

The current fragment shader doesn't differentiate between these modes, and renders fragments somewhat like the modulate instruction:

void main() {
  vec4 color = var_color;
  color *= texture(u_diffuse_map, var_diffuse_texcoord);
  color += var_offset_color;
  fragcolor = color;
}

We need to compile multiple versions of the fragment shader (using a preprocessor define to control the shading mode) and to then bind the appropriate shader when drawing each surface:
https://github.com/inolen/redream/blob/master/src/video/gl_backend.c#L520

To illustrate the problem, here's a problematic car in Crazy Taxi 2 captured with the tracer:
decal_alpha

And here's a TA trace you can load with redream decal_alpha.trace to step through the scene:
http://redream.io/decal_alpha.trace

@inolen inolen added bug medium labels Dec 6, 2016
@inolen inolen added hard and removed medium labels Dec 12, 2016
@mudlord
mudlord commented Dec 13, 2016

I must be missing something here.

why not use surf->shade in the shader as a uniform? that way, in the shader there can be a switch statement to specify the combiner formula,

@inolen
Owner
inolen commented Dec 13, 2016 edited

You're probably not missing much, I'm just not hip to modern graphics work.

Is the idea that
a.) the shader compiler will be smart and compile different versions of the shader based on that uniform
b.) gpu hardware has good branch prediction nowadays, misses are cheap

I don't really know if either of those are true, hence my suggestion of doing the precompiling ourselves.

@inolen inolen added medium and removed hard labels Dec 13, 2016
@mudlord
mudlord commented Dec 15, 2016 edited

I daresay on modern desktop systems, since the shader will be so small, I doubt it will affect performance. Mobile GPUs on the other hand are much more sensitive to things like branching in shaders, and for them, it does make a difference, so you might wanna keep that in mind if you do a ARM/MIPS port of redream.

I am running a GTX1070 so mine isnt the best GPU to check for performance on. Only things that really bog it down to me are things like my raymarch shaders (which have massive loops, with up to 100 iterations per pixel in cases)

I'm tempted to implement such a DC colour combiner shader out of boredom and I wanna see what the deal is with redream :) Is there a Slack or IRC channel for redream development?

@inolen
Owner
inolen commented Dec 15, 2016

@mudlord heh, I develop on an ultrabook with an intel iris 540. For this particular shader it's also probably possible to mix a uniform with step to perform the calculations without the switch / precompiling.

There is indeed a slack channel, slack.redream.io

@mudlord
mudlord commented Dec 15, 2016

A Iris? No wonder you are concerned about performance. :)

@inolen
Owner
inolen commented Dec 28, 2016 edited

Closing this with 1b811b6

Played with a step / switch implementation, but ended up falling back to preprocessing as that code path needed to be setup for other TSP/ISP settings (use_alpha / ignore_tex_alpha / offset).

@inolen inolen closed this Dec 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment