Forums > Jitter

Bonus Mirror Shaders

January 25, 2006 | 8:11 am

I finally got around to trying out thte mirror shaders from a few
weeks back. Did anyone else using 10.4.4 with a radeon mob 9700 have
trouble with the rf.kaleido.jxs shader? I get only a black screen
from it. The other ones work just fine.

thanks,
wes


January 25, 2006 | 8:35 am

I’ve been going through the shader bit by bit and I can get the
reflections to work, but I had to comment out the last section dealing
with folding with large offsets. I can’t seem to get that part to
work properly. Here’s the modded version:



kaleidoscope







< ![CDATA[

//setup for 2 texture
varying vec2 texcoord0;
varying vec2 texcoord1;
uniform vec2 size;
uniform vec2 scale;
uniform vec2 offset;
uniform vec2 origin;
uniform float div;
uniform sampler2DRect tex0;
uniform sampler2DRect tex1;
const float pi=3.1415926;

void main()
{
// where is the point?
vec2 sizea = abs(size);
vec2 point = abs(mod(texcoord0*scale+origin,sizea));

// cartesian to polar conversion
vec2 dt = point-0.5*sizea;
float radius = sqrt(dot(dt,dt)); //hypot
float theta = atan(dt.y,dt.x)+pi;
float phi = 2.*pi/div;

// fold theta in the range 0-phi
float foldtheta;

//reflect over radius at phi
foldtheta = mod(theta,phi*2.);
if (foldtheta>=phi)
foldtheta = phi – (foldtheta – phi);

// polar to cartesian conversion
vec2 no = vec2(-cos(foldtheta)*radius, -sin(foldtheta)*radius);
no = no+0.5*sizea;

// fold x and y in the range 0-size
float offx,offy,foldx,foldy;

offx = abs(no.x+offset.x);
foldx = mod(offx,sizea.x*2.);
//if (foldx>=sizea.x)
// foldx = sizea.x – (foldx-sizea.x);

offy = abs(no.y+offset.y);
foldy = mod(offy,sizea.y*2.);
//if (foldy>=sizea.y)
// foldy = sizea.y – (foldy-sizea.y);

vec2 not = vec2(offx,offy);
vec4 a = texture2DRect(tex0,not);

// output texture
gl_FragColor = a;
}
]]>


January 27, 2006 | 4:16 pm

Here’s the current state of the kaleido shader that I’ve got working
on my system. It seems that if I uncomment any more code, nothing
works. I find this quite strange as the code doesn’t do anything
malicious or unusual. Could it be I’m running out of memory to hold
the shader in? OS 10.4.4 pb 1.67 radeon mob 9700.

wes



kaleidoscope







< ![CDATA[

//setup for 2 texture
varying vec2 texcoord0;
varying vec2 texcoord1;
uniform vec2 size;
uniform vec2 scale;
uniform vec2 offset;
uniform vec2 origin;
uniform float div;
uniform sampler2DRect tex0;
uniform sampler2DRect tex1;
const float pi=3.1415926;

void main()
{
// where is the point?
vec2 sizea = abs(size);
vec2 point = abs(mod(texcoord0*scale+origin,sizea));

// cartesian to polar conversion
vec2 dt = point-0.5*sizea;
float radius = sqrt(dot(dt,dt)); //hypot
float theta = atan(dt.y,dt.x)+pi;
float phi = 2.*pi/div;

// fold theta in the range 0-phi
float foldtheta;

//reflect over radius at phi
foldtheta = mod(theta,phi*2.);
if (foldtheta>=phi)
foldtheta = phi – (foldtheta – phi);

// polar to cartesian conversion
vec2 no = vec2(-cos(foldtheta)*radius, -sin(foldtheta)*radius);
no = no+0.5*sizea;

// fold x and y in the range 0-size
float offx,offy;
float foldx,foldy;

offx = abs(no.x+offset.x);
offx = mod(offx, sizea.x);
//if (offx>=sizea.x)
// offx = sizea.x – (offx-sizea.x);

offy = abs(no.y+offset.y);
//offy = mod(offy, sizea.y);< --uncommented make nothing appear
//if (foldy>=sizea.y)
// foldy = sizea.y – (foldy-sizea.y);

vec2 not = vec2(offx,offy);
vec4 a = texture2DRect(tex0,not);

// output texture
gl_FragColor = a;
}
]]>


January 27, 2006 | 7:29 pm

Hi Wes,

This is most likely due to a limitation of the GLSL compiler’s
ability to handle multiple if statements. I think that this was
covered in a thread on one of the lists a while back. Note that any
if statement can be changed from a logical clause to an arithmetic
operation that always calculates all branches (which is required for
older gen cards which don’t support HW branching). This can sometimes
be faster than branching anyway, even on cards which support it,
since there is no pipeline flush. Depends on the complexity of the
branches of course.

So the statement:

if (foldtheta>=phi)
foldtheta = phi – (foldtheta – phi);

Can be rewritten as:

foldtheta = mix (foldtheta, phi – (foldtheta – phi), float
(foldtheta>=phi));

This converts the boolean to a floating point number zero or one,
used as the mixing coefficient in the arithmetic mix operator. If
zero, the first term is returned. If one, the second term is
returned. Make sense? This might seem wasteful, but as mentioned
before, it is supported on more hardware and often not even as
wasteful as a pipeline flush. It is also worth noting that oftentimes
with pixel processing shaders, the operation is more memory bound
than compute bound, as I would imagine this particular shader to be.

So replacing all the if statements below with the corresponding
arithmetic operation should make this shader work on your card. This
is what we did with most of the compositing shaders like
co.hardlight.jxs. A useful exercise would be to compare this version
with the version in the OpenGL Orange Book.

Let us know if you encounter further problems.

-Joshua


Viewing 4 posts - 1 through 4 (of 4 total)