La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Programmazione grafica in Java Creare effetti di luce tramite il filtro LightOp Redazione a cura di Luca Imperatore.

Presentazioni simili


Presentazione sul tema: "Programmazione grafica in Java Creare effetti di luce tramite il filtro LightOp Redazione a cura di Luca Imperatore."— Transcript della presentazione:

1 Programmazione grafica in Java Creare effetti di luce tramite il filtro LightOp Redazione a cura di Luca Imperatore

2 2 Creare effetti di luce tramite il filtro LightOp Nellesempio che segue vogliamo creare degli effetti di luce su di una composizione utilizzando il filtro LightOp di GLF. Luso di questo filtro ci permette di dare alla composizione un aspetto realistico grazie allutilizzo di mappe di rilievo e di luci opportunamente posizionate. La composizione è formata da tre livelli: lo sfondo, il testo e lombra del testo. Il livello di sfondo è realizzato caricando limmagine di una tessitura. Per dare un aspetto realistico allo sfondo facciamo agire su di esso il filtro LightOp. Prepariamo per questo una mappa di rilievo tramite la classe ElevationMap. Diamo al parametro boolean il valore true in modo da interpretare i valori di luminosità come rilievo a sporgere. Prepariamo le luci che illuminano la composizione: una luce direzionale ( DirectionalLight ) proveniente dallangolo in alto a sinistra e delle luci spot ( SpotLight ) provenienti dallalto e dal basso. Possiamo scegliere quali luci accendere agendo sui valori true e false delle rispettive variabili in fase di inizializzazione come vedremo successivamente in un esempio.esempio

3 3 Quindi possiamo creare la LitSurface alla quale passiamo come parametro la mappa di rilievo e alla quale aggiungiamo le luci precedentemente create. Infine trasformiamo lo sfondo in un livello di forma ( ShapeLayer ) necessario per far agire il filtro LightOp su di esso. La realizzazione del livello di testo segue gli stessi passi. Per avere un aspetto tridimensionale trasformiamo il testo in un livello di forma. Creiamo un nuovo filtro LightOp nel quale i parametri della LitSurface sono una nuova ElevationMap e le stesse luci create precedentemente. Quindi facciamo agire il filtro sulla ShapeLayer. Aggiungiamo infine un livello di ombra creato traslando la Shape del testo e sfocandola con il filtro ConvolveOp. Il risultato finale è il seguente:

4 4 Come prima cosa inizializziamo le variabili che ci serviranno per la composizione: //Font e colori del testo, colore dello sfondo e dellombra String text = "Java 2D is Hot!"; Color backgroundColor = new Color(204, 102, 51); Color textColor = new Color(118, 114, 195); Dimension size = new Dimension(600, 200); Font font = new Font("Curlz MT", Font.PLAIN, 90); File textureFile = new File("res/images/syberia/syberia35.jpg"); Color shadowColor = new Color(0, 0, 0); double lightIntensity = 2; //Posizionamento dellombra del testo int shadowOffsetX = 5, shadowOffsetY = 5; float shadowShearX = 0, shadowShearY = 0; //Luce spot dallalto Color lightTopRampColor = Color.white; boolean lightTopRamp = true; //Luce spot dal basso Color lightBottomRampColor = Color.white; boolean lightBottomRamp = false;

5 5 //Luce direzionale Color lightSunColor = Color.white; boolean lightSun = true; Trasformiamo il testo in un oggetto di tipo Shape che ci servirà successivamente per creare lombra e il livello del testo da filtrare: Shape shape = TextLayer.makeTextBlock(text, font, w, textTextAlignment); Position textPosition = new Position(textAnchor, 0, 0); shape = textPosition.createTransformedShape(shape, cmp.getBounds()); Creiamo il livello di sfondo caricando limmagine in una BufferedImage e modelliamo un rilievo tramite una mappa di rilievo ( ElevationMap ): String textureFileName = textureFile.getPath(); BufferedImage texture = Toolbox.loadImage(textureFileName, BufferedImage.TYPE_BYTE_GRAY);

6 6 ElevationMap map = new ElevationMap(texture, true, 5); Creiamo una LitSurface per lo sfondo alla quale aggiungiamo la luce direzionale proveniente dallangolo in alto a sinistra: LitSurface bkgSurface = new LitSurface(.3, 1, 1, materialType, map); if(lightSun) bkgSurface.addLight(new DirectionalLight(new double[]{-40, -40, 40}, lightSunIntensity, lightSunColor)); A questo punto prepariamo le luci spot ( SpotLight ) dallalto e dal basso che aggiungiamo alla LitSurface appena creata: //Creiamo la luce spot dallalto SpotLight[] topSpots = LightsStudio.getLightRamp(lightBounds, 4, Anchor.TOP, new double[]{lightIntensity, lightIntensity, lightIntensity, lightIntensity},

7 7 new Color[] {lightTopRampColor, lightTopRampColor, lightTopRampColor, lightTopRampColor},.5); if(lightTopRamp) bkgSurface.addLights(topSpots); //Creiamo la luce spot dal basso SpotLight[] bottomSpots = LightsStudio.getLightRamp(lightBounds, 3, Anchor.BOTTOM, new double[]{lightIntensity, lightIntensity, lightIntensity}, new Color[]{lightBottomRampColor, lightBottomRampColor, lightBottomRampColor}, 0); if(lightBottomRamp) bkgSurface.addLights(bottomSpots); Infine creiamo il filtro LightOp e lo facciamo agire sul livello di sfondo dopo averlo opportunamente trasformato in un livello di forma: LightOp op = new LightOp(bkgSurface); ShapeLayer backgroundLayer = new ShapeLayer(cmp, cmp.getBounds(), new FillRenderer(backgroundColor)); backgroundLayer.setRasterFilter(op);

8 8 E interessante notare come possiamo modificare la luminosità dello sfondo solamente agendo sui valori true e false delle variabili della luce direzionale e delle luci spot in fase di inizializzazione: Luci spot dallalto accese e dal basso spente. Luce direzionale spenta Luci spot dallaltospente e dal basso accese. Luce direzionale spenta Luci spot dallalto spente e dal basso accese. Luce direzionale accesa

9 9 Creiamo ora lombra del testo. Per dare un effetto realistico allombra utilizziamo il filtro ConvolveOp per ottenere un effetto di sfocatura e una AffineTransform per traslare la Shape del testo: ConvolveOp blurOp = new ConvolveOp(new GaussianKernel(5)); AffineTransform shadowTransform = AffineTransform.getShearInstance(shadowShea rX, shadowShearY); ShapeLayer shadowLayer = new ShapeLayer(cmp, shape, new FillRenderer(shadowColor)); shadowLayer.setRasterFilter(blurOp, new Dimension(5, 5)); shadowTransform.setToTranslation(shadowOffs etX, shadowOffsetY); shadowLayer.setTransform(shadowTransform); Dobbiamo ora dare un effetto tridimensionale al testo. Come per limmagine di sfondo creiamo una ElevationMap per modellare un rilievo: ElevationMap textMap = new ElevationMap(shape, 7, true, 10);

10 10 Creiamo una LitSurface per il testo alla quale aggiungiamo la luce direzionale e le luci spot create precedentemente: LitSurface textSurface = new LitSurface(.3, 1, 1, materialType, textMap); if(lightSun) textSurface.addLight(new DirectionalLight(new double[]{-40, -40, 40}, lightSunIntensity, lightSunColor)); if(lightTopRamp) textSurface.addLights(topSpots); if(lightBottomRamp) textSurface.addLights(bottomSpots); Quindi trasformiamo il testo in un livello di forma sul quale facciamo agire un nuovo filtro LightOp: ShapeLayer embossedText = new ShapeLayer(cmp, cmp.getBounds(), new FillRenderer(textColor)); embossedText.setRasterFilter(new LightOp(textSurface));

11 11 Per far agire il filtro solo sul livello di testo dobbiamo usare l'oggetto shape per creare una maschera ed eseguire un ritaglio ( clipping ). Tutto ciò che si trova all'interno dello shape rimane visibile ciò che sta al di fuori viene mascherato. embossedText.setLayerMask(shape); Lultima operazione consiste nel posizionare in una pila i tre livelli che abbiamo creato. Il livello più basso è quello di background, più su viene quello con lombra, ed infine il testo: cmp.setLayers(new Layer[]{ backgroundLayer, shadowLayer, embossedText }); Di seguito il codice completo del programma.

12 12 Lights.java import java.awt.*; import java.awt.geom.*; import java.awt.image.*; import java.awt.event.*; import java.io.*; import javax.swing.*; import com.sun.glf.*; import com.sun.glf.goodies.*; import com.sun.glf.util.*; public class Lights implements CompositionFactory { //Inizializziamo le variabili String text = "Java 2D is Hot!"; Color backgroundColor = new Color(204, 102, 51); Color textColor = new Color(118, 114, 195); Dimension size = new Dimension(600, 200); Font font = new Font("Curlz MT", Font.PLAIN, 90); File textureFile = new File("res/images/syberia/syberia35.jpg"); Color shadowColor = new Color(0, 0, 0); double lightIntensity = 2; //Posizionamento dellombra del testo int shadowOffsetX = 5, shadowOffsetY = 5; float shadowShearX = 0, shadowShearY = 0; //Luce spot dallalto Color lightTopRampColor = Color.white; boolean lightTopRamp = true; //Luce spot dal basso Color lightBottomRampColor = Color.white; boolean lightBottomRamp = false;

13 13 //Luce direzionale Color lightSunColor = Color.white; boolean lightSun = true; double lightSunIntensity = 0.2; int materialType = 16; //Posizione del testo Anchor textAnchor = Anchor.CENTER; TextAlignment textTextAlignment = TextAlignment.CENTER; public Composition build(){ LayerComposition cmp = new LayerComposition(size); int w = size.width; int h = size.height; //Trasformiamo il testo in una forma che ci servirà successivamente per creare l'ombra e il livello del testo Shape shape = TextLayer.makeTextBlock(text, font, w, textTextAlignment); Position textPosition = new Position(textAnchor, 0, 0); shape = textPosition.createTransformedShape (shape, cmp.getBounds()); //Creiamo il livello di sfondo caricando limmagine in una BufferedImage String textureFileName = textureFile.getPath(); BufferedImage texture = Toolbox.loadImage(textureFileName, BufferedImage.TYPE_BYTE_GRAY);

14 14 //Creiamo la mappa di rilievo long curTime = System.currentTimeMillis(); ElevationMap map = null; if(texture != null){ System.out.print("\nProcessing background elevations.... "); map = new ElevationMap(texture, true, 5); System.out.println("... Done : " + (System.currentTimeMillis()- curTime)/1000 + "(s)"); } //Creiamo la LitSurface per lo sfondo LitSurface bkgSurface = new LitSurface(.3, 1, 1, materialType, map); if(lightSun) bkgSurface.addLight(new DirectionalLight(new double[]{-40, -40, 40}, lightSunIntensity,lightSunColor)); //Creiamo la luce spot dall'alto int hm = 1; Rectangle lightBounds = new Rectangle(0, hm, w, h-2*hm); SpotLight[] topSpots = LightsStudio.getLightRamp(lightBounds, 4, Anchor.TOP, new double[]{lightIntensity, lightIntensity, lightIntensity, lightIntensity}, new Color[] {lightTopRampColor, lightTopRampColor, lightTopRampColor, lightTopRampColor},.5);

15 15 if(lightTopRamp) bkgSurface.addLights(topSpots); //Creiamo la luce spot dal basso SpotLight[] bottomSpots = LightsStudio.getLightRamp(lightBounds, 3, Anchor.BOTTOM, new double[]{lightIntensity, lightIntensity, lightIntensity}, new Color[]{lightBottomRampColor, lightBottomRampColor, lightBottomRampColor,}, 0); if(lightBottomRamp) bkgSurface.addLights(bottomSpots); LightOp op = new LightOp(bkgSurface); //Trasformiamo lo sfondo in un livello di forma sul quale facciamo agire il filtro LightOp ShapeLayer backgroundLayer = new ShapeLayer(cmp, cmp.getBounds(), new FillRenderer(backgroundColor)); backgroundLayer.setRasterFilter(op); //Creiamo il livello dell'ombra ConvolveOp blurOp = new ConvolveOp(new GaussianKernel(5)); AffineTransform shadowTransform = AffineTransform.getShearInstance (shadowShearX, shadowShearY); ShapeLayer shadowLayer = new ShapeLayer(cmp, shape, new FillRenderer(shadowColor)); shadowLayer.setRasterFilter(blurOp, new Dimension(5, 5));

16 16 shadowTransform.setToTranslation (shadowOffsetX, shadowOffsetY); shadowLayer.setTransform(shadowTransform) ; //Diamo un effetto tridimensionale al testo creando una mappa di rilievo curTime = System.currentTimeMillis(); System.out.print("\nCreating text elevation map.... "); ElevationMap textMap = new ElevationMap(shape, 7, true, 10); //Creiamo una LitSurface per il testo alla quale aggiungiamo la luce direzionale e le luci spot create precedentemente LitSurface textSurface = new LitSurface(.3, 1, 1, materialType, textMap); if(lightSun) textSurface.addLight(new DirectionalLight(new double[]{-40, -40, 40}, lightSunIntensity, lightSunColor)); if(lightTopRamp) textSurface.addLights(topSpots); if(lightBottomRamp) textSurface.addLights(bottomSpots); System.out.println("... Done : " + (System.currentTimeMillis()-curTime)/1000 + "(s)"); //Trasformiamo il testo in un livello di forma sul quale facciamo agire un nuovo filtro LightOp ShapeLayer embossedText = new ShapeLayer(cmp, cmp.getBounds(), new FillRenderer(textColor));

17 17 embossedText.setRasterFilter(new LightOp(textSurface)); //Per far agire il filtro solo sul livello di testo usiamo l'oggetto shape per creare una maschera ed eseguire un ritaglio embossedText.setLayerMask(shape); //Posizioniamo i livelli nella pila cmp.setLayers(new Layer[]{ backgroundLayer, shadowLayer, embossedText }); return cmp; } public static void main(String args[]){ JFrame f = new JFrame(); f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); Lights sf = new Lights(); CompositionComponent cc = new CompositionComponent(sf.build()); f.getContentPane().add(cc); f.pack(); f.setVisible(true); }


Scaricare ppt "Programmazione grafica in Java Creare effetti di luce tramite il filtro LightOp Redazione a cura di Luca Imperatore."

Presentazioni simili


Annunci Google