o'dium, a question about q2e

Discussion for Level editing, modeling, programming, or any of the other technical aspects of Quake
Post Reply
rep
Posts: 2910
Joined: Fri Aug 30, 2002 7:00 am

o'dium, a question about q2e

Post by rep »

Does Q2E support HLSL/.fx shaders, or does it use an arbitrary proprietary shader model format?

If .fx is supported, I could throw together a generic parallax shader to add true depth to all the normal maps in the game. (Or specifically for those objects with worldspace normals, since deformations often look silly with parallax bump mapping.)
[img]http://members.cox.net/anticsensue/rep_june.gif[/img]
o'dium
Posts: 11712
Joined: Sun Mar 25, 2001 8:00 am

Post by o'dium »

No, we dont, we use the same program format as Doom 3 does.

We can do paralax mapping but it requires bump maps. Its not that we cant do it and other things other ways (for example, soft per pixel shadows) its just that its not needed right now.
rep
Posts: 2910
Joined: Fri Aug 30, 2002 7:00 am

Post by rep »

No, you can grab the displacement/offset information from the normal map. It adds a stage to the shader, but doesn't add another image asset.

Soft shadows can be achieved with .fx as well, and they're not that expensive, especially if you just tag them onto dynamic models.
[img]http://members.cox.net/anticsensue/rep_june.gif[/img]
rep
Posts: 2910
Joined: Fri Aug 30, 2002 7:00 am

Post by rep »

Ever hear of steep parallax mapping? Rofl... Try this on for size:

Code: Select all


/** Color texture (with alpha) */
uniform sampler2D texture;
uniform vec3 wsEyePos;

/** xyz = normal, w = bump height */
uniform sampler2D normalBumpMap;

/** Multiplier for bump map.  Typically on the range [0, 0.05]
  This increases with texture scale and bump height. */
uniform float bumpScale;

varying vec3 tsL;

varying vec3 _tsE;
varying vec2 texCoord;
varying vec4 tan_X, tan_Y, tan_Z, tan_W;

void main(void) {

    // We are at height bumpScale.  March forward until we hit a hair or the 
    // base surface.  Instead of dropping down discrete y-voxels we should be
    // marching in texels and dropping our y-value accordingly (TODO: fix)
    float height = 1.0;

    // Number of height divisions
    float numSteps = 5;

    /** Texture coordinate marched forward to intersection point */
    vec2 offsetCoord = texCoord.xy;
    vec4 NB = texture2D(normalBumpMap, offsetCoord);

    vec3 tsE = normalize(_tsE);

    // Increase steps at oblique angles
    // Note: tsE.z = N dot V
    numSteps = mix(numSteps*2, numSteps, tsE.z);

    // We have to negate tsE because we're walking away from the eye.
    //vec2 delta = vec2(-_tsE.x, _tsE.y) * bumpScale / (_tsE.z * numSteps);
    float step;
    vec2 delta;


    // Constant in z
    step = 1.0 / numSteps;
    delta = vec2(-_tsE.x, _tsE.y) * bumpScale / (_tsE.z * numSteps);

        // Can also step along constant in xy; the results are essentially
        // the same in each case.
        // delta = 1.0 / (25.6 * numSteps) * vec2(-tsE.x, tsE.y);
        // step = tsE.z * bumpScale * (25.6 * numSteps) / (length(tsE.xy) * 400);

    while (NB.a < height) {
        height -= step;
        offsetCoord += delta;
        NB = texture2D(normalBumpMap, offsetCoord);
    }

    height = NB.a;

    // Choose the color at the location we hit
    const vec3 color = texture2D(texture, offsetCoord).rgb;

    tsL = normalize(tsL);

    // Use the normals out of the bump map
    vec3 tsN = NB.xyz * 2 - 1;

    // Smooth normals locally along gradient to avoid making slices visible.
    // The magnitude of the step should be a function of the resolution and
    // of the bump scale and number of steps.
//    tsN = normalize(texture2D(normalBumpMap, offsetCoord + vec2(tsN.x, -tsN.y) * mipScale).xyz * 2 - 1 + tsN);

    const vec3 tsH = normalize(tsL + normalize(_tsE));
    const float NdotL = max(0, tsL.z);
    const float NdotH = max(0, dot(tsN, tsH));
    float spec = NdotH * NdotH;

    vec3 lightColor = vec3(1.5, 1.5, 1) * 0.9;
    vec3 ambient = vec3(0.4,0.4,0.6) * 1.4;

    float selfShadow = 0;

    // Don't bother checking for self-shadowing if we're on the
    // back side of an object.
    if (NdotL > 0) {

        // Trace a shadow ray along the light vector.
        const int numShadowSteps = mix(60,5,tsL.z);
        step = 1.0 / numShadowSteps;
        delta = vec2(tsL.x, -tsL.y) * bumpScale / (numShadowSteps * tsL.z);

            // We start one iteration out to avoid shadow acne 
            // (could start bumped a little without going
            // a whole iteration).
            height = NB.a + step * 0.1;

            while ((NB.a < height) && (height < 1)) {
                height += step;
                offsetCoord += delta;
                NB = texture2D(normalBumpMap, offsetCoord);
            }

            // We are in shadow if we left the loop because
            // we hit a point
            selfShadow = (NB.a < height);

            // Shadows will make the whole scene darker, so up the light contribution
            lightColor = lightColor * 1.2;
        }
        }

        gl_FragColor.rgb = 
            color * ambient + color * NdotL * selfShadow * lightColor;

}
Edit: Rofl, someone got relief mapping to work in DOOM 3 by adding a depth (height) map generated from the normals to the alpha channel of the specular map, and a little shader wizardry.
[img]http://members.cox.net/anticsensue/rep_june.gif[/img]
Post Reply