topical media & game development
graphic-player-10-pixel-bender-shaders-parallax.pbk / pbk
<languageVersion : 1.0;>
kernel SteepParallaxMapping
< namespace : "com.derschmale";
vendor : "";
version : 1;
description : "Steep Parallax Mapping is a bump mapping technique that can create parallax movement and self-occlusion. The normal map that has to be provided must contain height data in the alpha channel.";
>
{
input image4 texture;
input image4 heightMap;
output pixel4 dst;
parameter float3 eyePosition
<
minValue : float3(-1000.0, -1000.0, -1000.0);
maxValue : float3(1000.0, 1000.0, 1000.0);
defaultValue : float3(0.0, 0.0, 1.0);
>;
parameter float bumpScale
<
minValue : 0.0;
maxValue : 1.0;
defaultValue : 0.05;
>;
parameter int steps
<
minValue : 1;
maxValue : 20;
defaultValue : 10;
>;
void evaluatePixel()
{
float height = 1.0;
float numSteps = float(steps);
float step;
float2 delta;
float2 offsetCoord = outCoord();
float3 eyeNorm = normalize(eyePosition);
float sampleHeight = sampleNearest(heightMap, offsetCoord).r;
numSteps = mix(numSteps*2.0, numSteps, eyeNorm.z);
step = 1.0/numSteps;
delta = eyePosition.xy * bumpScale / (eyePosition.z * numSteps);
/* can't loop, so hardcode the same piece over and over */
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
if (sampleHeight < height) {
height -= step;
offsetCoord += delta;
sampleHeight = sampleNearest(heightMap, offsetCoord).r;
}
dst = sampleNearest(texture, offsetCoord);
}
}
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.