Anuncios Google

Mapas de relieve en lua

Buenas, hace poco abrí un tema sobre esto aunque enfocado desde otro punto de vista, así que creo que es mejor abrir este.

 

Puede que sea un poco ambicioso, o que me aburra mucho, o las dos cosas, pero estuve intentando hacer este efecto en tiempo real en lua:

 

 

http://neilwallis.com/projects/java/bump/bump2.php

Podéis ver como funciona pinchando el link

He encontrado el código en java, pero no veo como podría traducirlo a lua para usarlo en la PSP, desde luego solo se podría usar con texturas-imágenes no muy grandes, pero no he visto ese efecto en ningún juego comercial de PSP.

Sin embargo, un coder de Nintendo DS lo consiguió usar en un juego homebrew, quedaba muy muy bien, y si la DS puede... :)

En Luadev, he conseguido algo similar, usando tres texturas, pero no termina de gustarme, además las texturas no funcionan muy bien en luadev, de momento, aquí tenéis un vídeo:

Aquí tenéis un demo con este ejemplo: http://dl.dropbox.com/u/757056/Bump_map%20test.zip

Para los que no se lo crean, el siguiente video muestra un demo que funcionaba en un PC 386-33, algo un poco más potente que una Super nintendo para que os hagais una idea, son modelos 3d muy simples con texturas animadas y con efecto bump map:

Por si alguien está interesado en mejorarlo, pego el código del efecto "Bump" en java.

Saludos

/**
 * 2D Bump Mapping of the OSAA logo
 *
 * Created by Rene Hangstrup Møller
 *
+ * Warming up for the Processing workshop at Open Space Aarhus
 * http://osaa.dk/wiki/index.php/Processingworkshops
 */
 
PImage colorImg; // color map for the logo
PImage heightImg; // height map for the logo
 
// will hold extracted height values from the height image.
int[] heightMap = new int[380*380];
 
// a spot-light light map will be calculated into this array
int[] lightMap = new int[380*380];
 
 
void setup() {
  // same size as the images
  size(380, 380);
 
  // load the color and height maps
  colorImg = loadImage("OSAA_LOGO.png");
  heightImg = loadImage("OSAA_BUMP.png");
 
  // calculate the light map
  for (int y = 0; y < 380; y++) {
    for (int x = 0; x < 380; x++) {
      // calculate the distance from the center of the lightmap to each pixel.
      // invert it so we have 255 in the center and 0 at the edges.
      // make sure the numbers are in the range [0-255]
      // this results in something that looks like a ball
      int d = constrain((int)(255 - 255 * dist(190, 190, x, y) / 190), 0, 255);
      lightMap[x + y * 380] = d;
    }
  }
 
  // extract the blue channel from the bump map - and use that as height value 
  for (int y = 0; y < 380; y++) {
    for (int x = 0; x < 380; x++) {
      // blue is in the last 8 bits, which we get with the bitmask 0xff
      heightMap[x + y * 380] = heightImg.get(x, y) & 0xff;
    }
  }
 
}
 
void draw() {
  // move the light in harmonic curves
  int lightX = (int)(200 * cos(millis()/1000.0));
  int lightY = (int)(200 * sin(millis()/3000.0));
 
  // prepare the pixels array for the screen
  // we dont need the current pixel data, but the documentation seems to hint
  // that we should do it anyway before accessing the pixels[] array.
  loadPixels();
 
  // we skip a 1 pixel border of the screen to accomodate for the gradient calculation
  for (int y = 1; y < 379; y++) {
    for (int x = 1; x < 379; x++) {
      // calculate the gradient at each pixel, by comparing the height of neighbouring pixels
      int dx = heightMap[(x-1) + y * 380] - heightMap[(x+1) + y * 380];
      int dy = heightMap[x + (y-1) * 380] - heightMap[x + (y+1) * 380];
 
      // calculate where to read the light intensity from the light map
      // start with current pixel position
      // offset by the light position
      // and offset it further based on the gradient values (dx, dy)
      // we double the gradient to make edges more visible.
      // try multiplying with four instead for more dramatic bumps :-)
      // finally make sure to clamp values to within light map range [0-379]
      int lx = constrain(lightX + x + dx * 2, 0, 379);
      int ly = constrain(lightY + y + dy * 2, 0, 379);
 
      // lookup light intensity from the light map and add a small amount of ambient light
      int intensity = lightMap[lx + ly * 380] + 16;
 
      // read the pixel color form the color map
      color p = colorImg.get(x, y);     
 
      // multiply light intensity with each color component and clamp to range [0-255]
      int r = min(255, (int)((red(p)) * intensity / 256.0));
      int g = min(255, (int)((green(p)) * intensity / 256.0));
      int b = min(255, (int)((blue(p)) * intensity / 256.0));
 
      // output the calculated pixel
      pixels[x + y *380] = color(r, g, b);
    }
  }  
 
  // copy pixel[] to screen buffer
  updatePixels();
}

 

 


Pobre PSP


Anuncios Google

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Mills

Pues

Al final era una perdida de tiempo, porque me he dado cuenta que la PSP tiene bastante potencia para procesar objetos 3d sin necesidad de usar estos trucos de bump mapping, como prueba, he generado un objeto 3d a partir de esas texturas y lo he iluminado en luadev.

El objeto tiene unas 34.000 caras, que equivaldrían a una textura de 184x184 pixeles, y la PSP está calculando la iluminación de todas las caras a partir de los vectores, como haria el efecto bump map, solo que no es una textura, sino que es un objeto real* (funciona a 120 fps pero el remotejoy lo ralentiza un poco).

 

Saludos.


Pobre PSP

Imagen de NEKERAFA

O.O

Y no sé porque Sony se niega a dar soporte a la scene, porque visto lo visto...

Imagen de Mills

Bueno

Por lo poco que se, no suelen ganar dinero exprimiendo el hardware, hacen 4 imagenes de pajaritos con un fondo bonito (como un juego muy de moda ahora) y ya está.


Pobre PSP

Exacto...

Desinteres en un aparato que podría llegar a cosas tan impresionantes como las de un iPhone... y no bromeo, visto lo visto.

Imagen de Mills

Funcionó... pero...

Gracias a Chimecho, que ha traducido a lua ese código, he podido probarlo en la PSP.

Lo primero decir, que he buscado por la red en foros del siglo pasado (si... de los 90) para ver como hacian este efecto, en aquellos demos del Amiga e incluso del C64...

Bien, la forma de hacer estos "bump maps 2d" en aquellas "prehistóricas" máquinas (con perdón) era idéntica a la del código que he probado en PSP, pero hay un problema, y es que en PSP funciona muy muy lento.

Para hacer el siguiente frame, la PSP estuvo un minuto con la pantalla en negro.. como muerta, casi se podría decir que este es el primer "render" que hace una PSP... que sepamos jeje:

He testeado varias formas de blitear los pixeles y he encontrado que, aunque no debería ser así, el for reduce mucho el rendimiento, mientras que si uso muchos image.blit por separado, el rendimiento es muy superior, incluso si la imagen es muy pequeña (lo probé en una imagen de 6x6)

Bueno, el código funciona, es el mismo que usaron en demos para Amiga o C64 en los 90, así que el problema no es la potencia (LuadevR0 esta bastante optimizado), el problema es... no tengo ni idea jeje.

Saludos :)

 


Pobre PSP

Imagen de Andresmargar

Me ha parecido C

Pues a mi eel codigo me ha parecido C, no Java...

Son muy parecidos.

Son muy parecidos.

Ya sabía yo...

Que el for era algo problemático con el rendimiento... me daba esa sensación con iThunder OS...

Gracias por hacer la prueba.

Un saludo.


 

 

Es raro, pero cierto. Hice un

Es raro, pero cierto. Hice un mini-benchmark con este code:

img=image.load("LM.png")
tmr=timer.new()
 
tmr:start()
  img:blit(0,0)
    --334 líneas parecidas aquí...
  img:blit(460,260)
screen.flip()
 
time1=tmr:time()
  tmr:stop()
    tmr:reset()
tmr:start()
 
for i=0,23 do
	for j=0,13 do
		img:blit(i*20,j*20)
	end
end
screen.flip()
 
time2=tmr:time()
  tmr:stop()
    screen.print(5,5,"T1: "..time1.."\nT2: "..time2)
  screen.flip()
controls.waitforkey()

La salida fue:
TM1: 6  -->muchas líneas
TM2: 10  -->for

Una diferencia... intangible realmente, que supongo se genera por las operaciones aritméticas que se hacen en el for.
Espero que Dev pueda hacer algo con esto.

Ojalá lea estas páginas...

Y le de por crear un "DevFor" jajajaj

Imagen de Mills

Bueno estuve probándolo con

Bueno estuve probándolo con deviante, me dijo que el for es bastante lento en luadev y por eso el problema...

Estoy probando otro script en el que ha sustituido el for por otra función equivalente, no conseguí que funcionase del todo, pero logré que mostrase los fps mientras hacia la 1ª operación, la de calcular la inclinación de los pixeles, metida en un while, y el resultado fueron 20 fps, que supongo que son 10, con una imagen pequeña, de 32x32, así que creo que estamos igual :(.

La verdad es que lo he intentado compilar en c, pero soy incapaz, se supone que en c, el for no daría esos problemas, pero bueno, yo no sé compilarlo.

Aquí hay un código similar, muy sencillo pero en c, usando for": http://www.flipcode.com/archives/ta-demo07.zip

Es de una página acerca de demos y contiene muchos codigos para efectos conocidos, como plasma, ondas etc... Para todos ellos, se necesita un control "per-pixel" es decir, que hay que dibujar pixel por pixel cada imagen, cosa que el for en c, parece hacer muy bien, habrá que esperar para verlo con lua, supongo.

De todas formas aquí tenéis el codigo en lua con los for y las dos imágenes (con el que hice "el render") para quien quiera probarlo: http://dl.dropbox.com/u/757056/bump%20mapping.zip

Podéis reducir las imágenes para que funcione más rápido.

Otra cosa que he pensado, es usar las funciones de suma y resta de colores, image.fxsub image.fxadd, ya que estas funciones realizan una operación por cada pixel (sumar color y restar color), se podría modificar de alguna forma. Aunque yo las he intentado usar y se me muere la PSP (se queda en negro y se apaga). No se si las estoy usando bien, pero se supone que funcionan igual que un image.blit...

Saludos.


Pobre PSP

Imagen de Chimecho

Mmmm...

Sé Java, pero sin las imágenes OSAA_*.png no logro comprenderlo del todo.

Imagen de Mills

Las imágenes OSAA

OSAA logo es un png de lo que quieras, en ese caso un logo.

OSAA Bump es otro png pero contiene el mapa de alturas del logo, es decir, una imagen en blanco y negro, con las partes mas altas en blanco, y las más bajas en negro.

Con eso calcula la orientación del pixel sin tener que calcular pixel por pixel, (lo cual ralentizaría mucho el proceso) algo así, viene explicado en ingles. el la página de donde saqué la primera imagen.


Pobre PSP

Imagen de Chimecho

Ok

Intentaré traducir el código ese

Imagen de Mills

Mira he hecho este ejemplo,

Mira he hecho este ejemplo, asi en un rato.. se supone que con dos imagenes como estas funciona:

Una imagen "normal":

 

Y su mapa de alturas (este me ha quedado un poco mal jeje):

 

 


Pobre PSP

Imagen de Chimecho

Pos

Pruébalo: http://pastebin.com/00c9YUXW

Que recién voy a desayunar xD

Imagen de Mills

No me deja verlo, enviamelo

No me deja verlo, enviamelo mejor al msn luego :)

 

Imagen de Chimecho

Nah

Ya lo hice public, toma: http://pastebin.com/HiVNNnHY

No funciona si pones el

No funciona si pones el objeto 3D y mueves el foco de luz?

Imagen de Mills

Se trata de simplificar los

Se trata de simplificar los objetos, un plano con este efecto deja de ser un plano, para pasar a ser una superficie rugosa, o por ejemplo agua.
Si lo haces en 3d necesitas muchísimos vértices, además se puede usar sin necesidad de objetos 3d, por ej imagínate un juego estilo mario bros, con esto, de hecho, existió alguno en la época del MS-DOS pero no recuerdo dónde y cuando lo ví.


Pobre PSP

Si te interesa mi opinión, lo

Si te interesa mi opinión, lo que mencionas no es más que complicarse la vida innecesariamente xD

Tan solo piensa que tendrías que dibujar las sombras una por una, lo cual exigiría una cantidad bestial de cálculos por tener que trabajar individualmente con cada pixel. La psp podría con eso, si, pero si lo vas a meter a un homebrew no me parece viable en lo absoluto.

Imagen de Mills

Bueno eso pensaba yo, pero lo

Bueno eso pensaba yo, pero lo hicieron en Nintendo DS y el juego funcionaba a 60 fps, es cierto que la textura era muy simple pero se puede, si no, ni lo intentaría.

Además ya te dije que lo vi en la era MS-DOS con procesadores estilo Play Station 1, o en demos homebrew del Amiga 1200.

Solamente hay que saber como cambiar el color de los píxeles de la misma forma que se usa la suma y resta de colores en lua, pero no se muy bien como.

He conseguido algo parecido pero no me acaba de gustar (actualicé el 1º post para que lo veas).

Saludos.


Pobre PSP

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.