Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

Indagando con el blend_type

Ver el tema anterior Ver el tema siguiente Ir abajo

Indagando con el blend_type

Mensaje por Eron el 2013-02-05, 09:55

¡Hola fanáticos del script! Últimamente me aburro mucho, quizá os habréis fijado xDD!

Hoy decidí investigar sobre el blend_type, uno de esos misterios que oculta Enterbrain.

Hasta donde sé, el método que el maker usa para hacer los blend_type es un misterio.
He llegado a la conclusión de que el blend_type no puede ser viable usando solo el sprite en cuestión, sinó que tiene que ser una relación entre el color del sprite, y lo de debajo.
Algo así, por ejemplo:

Código:
def blend_type=(blend_type)
   when 0
      color = color_sprite
   when 1
      color = color_sprite + color_back
   when 2
      color = color_sprite - color_back
   end
   return color # o set_pixel
end

No sé como se suman los colores, igual hay que usar cada componente (red, green, blue, alpha) a parte, pero eso da lo mismo.
Entonces la pregunta es; vale, obtener el color del sprite (lo que yo llamé color_sprite en el ejemplo) es facil, sería con un get_color, que ya viene definido en su bitmap. ¿Pero y para obtener el otro color?
¡No hay un get_pixel de una viewport! ¿Entonces cómo?...

Pensé en la posibilidad de consiguiera esa fórmula haciendo que el color ese fuera o un equivalente, o un aditor, o un substractor, pero sin conocer lo que está sustituyendo/sumando/restando.

Código:
def blend_type=(blend_type)
   when 0
      color_formula = "="
   when 1
      color_formula = "+="
   when 2
      color_formula = "-="
   end
end

Pero no le veo lógica alguna, porque algo tendrá que hacer luego con eso x'DDD
Además, he buscado por ahí, y ninguno de los blend que he encontrado por ahí usa solo un color, siempre es entre dos colores (y a veces, además alpha), así:

Código:
module ColorMath
  # Blend two or more colours and return a new colour.
  module Blend
    def alpha(ca, cb, alpha)
      for_rgb(ca, cb){ |a, b| (alpha * b + (1 - alpha) * a) }
    end
    extend self
  private
    def for_rgb(a, b, &blk)
      RGB.new(*([:red, :green, :blue].map{ |channel|
        blk.call(a.__send__(channel), b.__send__(channel))
      }))
    end
  end
end

def blend(a, b, alpha)
  ColorMath::Blend.alpha(ColorMath::hex_color(a), ColorMath::hex_color(b), alpha).hex
end

Código:
def blend(col_a, col_b, alpha)
  newcol = []
  [0,1,2].each do |i|
    newcol[i] = (1.0 - alpha) * col_a[i] + alpha * col_b[i]
  end
  newcol
end

Código:
def blend(c1, c2)
  (0..2).map{ |i| (c1[i]*(0xFF-c2[3]) + c2[i]*c2[3]) >> 8 }
end

Código:
class Color
    def blend color
      return Color.new(((r + color.r) / 2), ((g + color.g) / 2),
                      ((b + color.b) / 2), ((a + color.a) / 2))
    end
end

Siempre entre dos colores.

Por lo tanto volvamos a lo de antes. Será que hace un get_pixel a todo lo que tiene debajo (o a la propia screen) y otro al propio sprite y luego haca operación.
¿Cómo? Se me ocurrieron dos maneras... La primera es mirando los pixeles de cada capa definida hasta el momento hasta obtener el conjunto de todo lo que hay debajo del sprite.
Por ejemplo, hacer un get_pixel del panorama, agregarle el get_pixel del tilemap, luego otro con los charas, y otro con las fog (vaya, todo lo que tenga z menor a la z del sprite) y luego
con todo eso, hacer la puñetera operación con el get_pixel pertinente del sprite. ¡Pero qué locura! ¿Cómo no morimos por el lag?
La otra que se me ocurrió fue que hiciera algo así como una "captura de pantalla" invisible antes de poner ese sprite, y luego esa captura de pantalla volviera a cargarla como si fuera un propio sprite para poder obtener sus colores. Igualmente loco, pero quizá no tanto.
¿Me estoy volviendo majara? ¿Tenéis alguna idea mejor de cómo puede hacerse ese shader o blend o lo que sea?

A este paso acabará no haciéndome caso nadie x'DD
avatar
Eron
Principiante
Principiante

0/3

Créditos 3599

Gracias : 60

Volver arriba Ir abajo

Re: Indagando con el blend_type

Mensaje por Wecoc el 2013-02-05, 15:47

A este paso al final tendremos que hacer una sección de "Paranoias raras" solo para tí xD

No creo que blend_type y el color en sí tengan tanto en común como parece en el maker.
Creo que el blend_type actúa simplemente como un Shader, en concreto, como un Pixel shader.

Los Pixel shader calculan el color y otros atributos de cada fragmento. Varían siempre de UN solo color, variando luminosidad, aplicando efectos (como ese odioso relieve xD), sombras, reflejos especulares, translucidez y otras cosas que me estoy inventando sobre la marcha. Lo malo de esta cosa, y más aún en RPG maker, es que al operar con un solo color no se pueden crear efectos complejos, sin embargo, en algo te acercaste y es que usan algo similar a un get_pixel, más que nada para checkear la coordenada a la que el efecto está siendo aplicado.

Esta misma técnica puede habilitar una amplia variedad de efectos de post-procesamiento de dos dimensiones, como la falta de definición (blur), o detección de bordes, el pixelado y algunas otras cosas que si te interesan las encontraras en un script que posteé en un topic de newold sobre las Bitmap.
avatar
Wecoc
Administrador
Administrador



Créditos 12312

Gracias : 571

Volver arriba Ir abajo

Re: Indagando con el blend_type

Mensaje por orochii el 2013-02-05, 17:35

No sé si exactamente pixel shader xD, pero el blend_type digamos que funciona a "bajo nivel", no al nivel de Ruby. Recuerda que en el RGSS no todo está en Ruby, cosas como el Tilemap están escritas en C/C++. Lo que maneja al sprite en sí y lo dibuja en pantalla es otra de las cosas que están a bajo nivel (C/++), y por lo tanto el blend es manejado de esa forma.

Para hacerlo en Ruby, necesitarías accesar a los datos de la pantalla JUSTO ANTES de que ocurra el dibujado del sprite en ella. Y para ello necesitarías hacer cambios en el update del Graphics (cosa que o es imposible o para nada recomendable xD...).
La otra opción que tienes es, que al crear cualquier sprite/plane/asdf, lo agregues a una lista, y vayas iterando entre ellos y sus posiciones, e ir calculando el color resultante a partir de get_pixel y haciendo malabares si te encuentras con uno que tenga un blend distinto...

Pero bueno, digamos que no es imposible x'D,
Orochii Zouveleki
avatar
orochii
Reportero

0/3

Créditos 7613

Gracias : 412

Volver arriba Ir abajo

Re: Indagando con el blend_type

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.