m@Xist

10 October 2006, 12:06 AM

Hi folks

The book Texturing and Modeling, A Procedural Approach contains code for a noise-based procedural flame shader. This code is written in the Stanford shading language (RTSL).

float abs(float x) {

return(select(x < 0, -x, x));

}

float fastspline(float x) {

float t0 = x*2;

float r0 = 0.8 + t0*(-0.45 + t0*(-0.8 + t0*(0.55)));

float t1 = (x-0.5)*2;

float r1 = 0.1 + t1*(-0.4 + t1*(0.55 + t1*(-0.25)));

float r = select(x < 0.5, r0, r1);

return r;

}

float3 rotate30scale2(float3 x) {

return {x[0]*2.0*0.866, x[1]*2.0*(-0.5), 0.0} + {x[0]*2.0*0.5, x[1]*2.0*(-0.866), 0.0};

}

float noise3D(float3 T, texref noisetex,

float3 L1offset, float L1weight,

float3 L2offset, float L2weight) {

float L1 = texture(noisetex, T+L1offset)[0];

float L2 = texture(noisetex, T+L2offset)[0];

float N = L2*L2weight + L1*L1weight; // Range of N is [0,1]

return abs(N-0.5);

}

float lookup_olddepth(texref depthtex) {

float4 dtex = texture(depthtex, rgb(xyz_xcreen())/1024);

return dtex[0] + dtex[1]/256 + dtex[2]/(256*256);

}

surface shader float4

flame (float4 uv, primitive group float time, texref permutetex, texref noisetex, texref depthtex) {

fragment float u = uv[0];

fragment float v = uv[1];

float framediff = time*0.2;

float3 T = {u, v+framediff, 0}

constant float freqscale = 16;

T = T * ({freqscale, freqscale/2, 0} * {1/64.0, 1/64.0, 0});

constant float changerate = 6.0;

float timeval = time*changerate;

float timerem = timeval - floor(timeval);

float timebase = floor(timeval);

float L1weight = 1.0 - timerem;

float L2weight = timerem;

float ocoord1 = timebase/64.0 + 1.0/128.0;

float ocoord2 = ocoord1 + 1.0/64.0;

float3 L1offset = rgb(texture(permutetex, {ocoord1, 1.0/128.0, 0.0}));

float3 L2offset = rgb(texture(permutetex, {ocoord2, 1.0/128.0, 0.0}));

float turb;

turb = noise3D(T, noisetex, L1offset, L1weight, L2offset, L2weight);

T = rotate30scale2(T);

turb = turb + 0.5 * noise3D(T, noisetex, L1offset, L1weight, L2offset, L2weight);

T = rotate30scale2(T);

turb = turb + 0.25 * noise3D(T, noisetex, L1offset, L1weight, L2offset, L2weight);

T = rotate30scale2(T);

turb = turb + 0.125 * noise3D(T, noisetex, L1offset, L1weight, L2offset, L2weight);

float turbscale = 0.5 + 0.7*(1-v);

float x = (1.0/sqrt(v)) * (abs(2.0*u-1.0) + turbscale*turb);

float edgedensity = 12.5 * fastspline(clamp(x, 0, 1));

float FlameTemperature = 0.6;

float3 FlameColor = {1.0, FlameTemperature, FlameTemperature-0.2};

float3 edgecolor = FlameColor * edgedensity;

float indensity = (2.85*turb+0.55) + v*0.35;

float incolor = FlameColor * indensity;

float3 flamecolor = select(edgedensity > indensity, incolor, edgecolor);

float density = select(edgedensity > indensity, indensity, edgedensity);

flamecolor = clamp(flamecolor, 0, 1);

density = clamp(density, 0, 1);

constant float depthscale = 0.002;

constant float flamethickness = depthscale;

constant float depthperturb = 1.75 * depthscale;

constant float edgeperturb = 3.5 * depthscale;

float olddepth = lookup_olddepth(depthtex);

float depth = xyz_screen()[2];

depth = depth + depthperturb*turb + edgeperturb*abs(u-0.5);

float atten = (olddepth - depth) / flamethickness;

return {flamecolor, density*min(atten, 1.0)};

} // flame

Code (c)2001 NVIDIA

How can I use this shader. There are some commands like "select", which is not defined in e.g. FXComposer. I'm a rookie in such things, but probably it's possible to re-write this code to another language?

Thanks for helping me.

The book Texturing and Modeling, A Procedural Approach contains code for a noise-based procedural flame shader. This code is written in the Stanford shading language (RTSL).

float abs(float x) {

return(select(x < 0, -x, x));

}

float fastspline(float x) {

float t0 = x*2;

float r0 = 0.8 + t0*(-0.45 + t0*(-0.8 + t0*(0.55)));

float t1 = (x-0.5)*2;

float r1 = 0.1 + t1*(-0.4 + t1*(0.55 + t1*(-0.25)));

float r = select(x < 0.5, r0, r1);

return r;

}

float3 rotate30scale2(float3 x) {

return {x[0]*2.0*0.866, x[1]*2.0*(-0.5), 0.0} + {x[0]*2.0*0.5, x[1]*2.0*(-0.866), 0.0};

}

float noise3D(float3 T, texref noisetex,

float3 L1offset, float L1weight,

float3 L2offset, float L2weight) {

float L1 = texture(noisetex, T+L1offset)[0];

float L2 = texture(noisetex, T+L2offset)[0];

float N = L2*L2weight + L1*L1weight; // Range of N is [0,1]

return abs(N-0.5);

}

float lookup_olddepth(texref depthtex) {

float4 dtex = texture(depthtex, rgb(xyz_xcreen())/1024);

return dtex[0] + dtex[1]/256 + dtex[2]/(256*256);

}

surface shader float4

flame (float4 uv, primitive group float time, texref permutetex, texref noisetex, texref depthtex) {

fragment float u = uv[0];

fragment float v = uv[1];

float framediff = time*0.2;

float3 T = {u, v+framediff, 0}

constant float freqscale = 16;

T = T * ({freqscale, freqscale/2, 0} * {1/64.0, 1/64.0, 0});

constant float changerate = 6.0;

float timeval = time*changerate;

float timerem = timeval - floor(timeval);

float timebase = floor(timeval);

float L1weight = 1.0 - timerem;

float L2weight = timerem;

float ocoord1 = timebase/64.0 + 1.0/128.0;

float ocoord2 = ocoord1 + 1.0/64.0;

float3 L1offset = rgb(texture(permutetex, {ocoord1, 1.0/128.0, 0.0}));

float3 L2offset = rgb(texture(permutetex, {ocoord2, 1.0/128.0, 0.0}));

float turb;

turb = noise3D(T, noisetex, L1offset, L1weight, L2offset, L2weight);

T = rotate30scale2(T);

turb = turb + 0.5 * noise3D(T, noisetex, L1offset, L1weight, L2offset, L2weight);

T = rotate30scale2(T);

turb = turb + 0.25 * noise3D(T, noisetex, L1offset, L1weight, L2offset, L2weight);

T = rotate30scale2(T);

turb = turb + 0.125 * noise3D(T, noisetex, L1offset, L1weight, L2offset, L2weight);

float turbscale = 0.5 + 0.7*(1-v);

float x = (1.0/sqrt(v)) * (abs(2.0*u-1.0) + turbscale*turb);

float edgedensity = 12.5 * fastspline(clamp(x, 0, 1));

float FlameTemperature = 0.6;

float3 FlameColor = {1.0, FlameTemperature, FlameTemperature-0.2};

float3 edgecolor = FlameColor * edgedensity;

float indensity = (2.85*turb+0.55) + v*0.35;

float incolor = FlameColor * indensity;

float3 flamecolor = select(edgedensity > indensity, incolor, edgecolor);

float density = select(edgedensity > indensity, indensity, edgedensity);

flamecolor = clamp(flamecolor, 0, 1);

density = clamp(density, 0, 1);

constant float depthscale = 0.002;

constant float flamethickness = depthscale;

constant float depthperturb = 1.75 * depthscale;

constant float edgeperturb = 3.5 * depthscale;

float olddepth = lookup_olddepth(depthtex);

float depth = xyz_screen()[2];

depth = depth + depthperturb*turb + edgeperturb*abs(u-0.5);

float atten = (olddepth - depth) / flamethickness;

return {flamecolor, density*min(atten, 1.0)};

} // flame

Code (c)2001 NVIDIA

How can I use this shader. There are some commands like "select", which is not defined in e.g. FXComposer. I'm a rookie in such things, but probably it's possible to re-write this code to another language?

Thanks for helping me.