1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
package org.sunflow.core.shader;
import org.sunflow.SunflowAPI;
import org.sunflow.core.ParameterList;
import org.sunflow.core.Ray;
import org.sunflow.core.ShadingState;
import org.sunflow.core.Texture;
import org.sunflow.image.Color;
import org.sunflow.math.Vector3;
public class TexturedShinyDiffuseShader extends ShinyDiffuseShader {
private Texture tex;
public TexturedShinyDiffuseShader() {
tex = null;
}
@Override
public boolean update(ParameterList pl, SunflowAPI api) {
String filename = pl.getString("texture", null);
if (filename != null)
// EP : Made texture cache local to a SunFlow API instance
tex = api.getTextureCache().getTexture(api.resolveTextureFilename(filename), false);
return tex != null && super.update(pl, api);
}
@Override
public Color getDiffuse(ShadingState state) {
return tex.getPixel(state.getUV().x, state.getUV().y);
}
// EP : Added transparency management
@Override
public Color getRadiance(ShadingState state) {
float alpha;
if (isOpaque() || (alpha = tex.getOpacityAlpha(state.getUV().x, state.getUV().y)) > 0.99999) {
// Pixel is fully opaque
return super.getRadiance(state);
} else {
// Ignore shininess for half transparent pixels
state.faceforward();
state.initLightSamples();
state.initCausticSamples();
Color c = state.diffuse(getDiffuse(state));
Vector3 refrDir = state.getRay().getDirection();
Color refraction = state.traceRefraction(new Ray(state.getPoint(), refrDir), 0);
return c.mul(alpha).madd(1 - alpha, refraction);
}
}
@Override
public boolean isOpaque() {
return !(tex.isTransparent());
}
@Override
public Color getOpacity(ShadingState state) {
return tex.getOpacity(state.getUV().x, state.getUV().y);
}
// EP : End of modification
}
|