top of page
Foto del escritorBraulio Madrid

Censura o pixelación, como ejercerla y no morir en el intento.



Hace alrededor de un año, varios blogs que escribí fueron censurados, los temas político si que los entiendo, mi postura puede no gustar a algunos y eso es lógico, lo que no entiendo porqué, son algunos tutoriales que tenía programados y que no salieron a la luz. En el blog anterior reescribí de nuevo un tutorial de esos que nunca salió a la luz y esta vez pensé en publicar otro de esos tutoriales que nunca salió a la luz.


Entonces pensé en dedicarle un tema a la #censura o #pixelacion, pero no desde el punto de vista que creen, solo desde el punto de vista técnico de la generación de imágenes, que más cabe decir, el efecto se explica por sí solo, antiguamente utilizado para la transición de escenas en juegos de supernintendo, un tiempo más cercano era usado en juegos hentai en 3D para censurar genitales y actualmente es usado en algunos juegos modernos con temática retro para el llamado pixel perfect, aunque de esto último no estoy tan seguro.


Lo cierto es que el tema del Blog anterior se detalló el tema de la modificación de las coordenadas uv para generar distorsión, esta vez será una aplicación nueva de lo mismo. esta vez vamos quitarle datos a las coordenadas uv para obtener una imagen de calidad pésima haciendo que este se quede en censura o pixelación.


En nuestro shader solo incluiremos 2 parámetros simplemente, la textura que nos envía la cámara y un flotante que será el tamaño de nuestro pixel


Properties {
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
		_CellSize("CellSize", range(0,0.1)) = 0.1
	}

A continuación haremos el #subshader con los #preprocesadores de siempre y pasar los parámetros que obtenemos de las propiedades. hasta aquí nada del otro mundo, vaya al anterior blog para enterarse cómo se hace esta parte.


SubShader {
		Pass{
			CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment frag
			#pragma fragmentoption ARB_precision_hint_fastest
			#include "UnityCG.cginc"

			uniform sampler2D _MainTex;
			fixed _CellSize;

Ahora si vamos a la parte central del asunto y es la función o programa de fragmentos, que tendrá como parámetro el struct que genera el programa de vértices.

vamos a declarar la variable finalcolor que será el valor a retornar, pero como puede ver, su valor está condicionado por el tamaño del pixel _CellSize, esto es por la sencilla razón de que dividir por cero genera un número infinito, o error o un NaN(not a number), que es lo mismo. por eso el valor de la variable final color es un uso simple de un tex2D();


else 	finalColor = tex2D(_MainTex, i.uv);

Lo importante viene en esta variable steppedUV, lo que se hace es tomar el valor de las coordenadas UV y lo dividimos por el tamaño del píxel, lo redondeamos para que pierda detalle y al resultado lo multiplicamos por el tamaño del pixel. Esto parecerá no tener sentido el hecho de dividir para luego multiplicar. Lo que ocurre es que dividir tiene el efecto de reducir el tamaño de la imagen, al redondear el valor, lo que hacemos es eliminar esos detalles que no necesitamos y al volver a multiplicar, re-escalamos la imágen al tamaño original, pero el redondeo le hizo perder detalles.


float2 steppedUV = round(i.uv / _CellSize)*_CellSize;

Ya lo que resta es aplicar nuestra función tex2D a la imagen con las nuevas coordenadas uv que calculamos

fixed4 frag(v2f_img i) : COLOR {
	fixed4 finalColor;
	if (_CellSize > 0) 
	{ 
		float2 steppedUV = round(i.uv / _CellSize)*_CellSize; 
		finalColor = tex2D(_MainTex, steppedUV);
	}
	else 	finalColor = tex2D(_MainTex, i.uv);
	
	return finalColor;
	}
	ENDCG

Aquí el shader completo.

Shader "Image FX/Pixelation" {
	Properties {
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
		_CellSize("CellSize", range(0,0.1)) = 0.1
	}
	SubShader {
		Pass{
			CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment frag
			#pragma fragmentoption ARB_precision_hint_fastest
			#include "UnityCG.cginc"

			uniform sampler2D _MainTex;
			fixed _CellSize;
			
			fixed4 frag(v2f_img i) : COLOR {
				fixed4 finalColor;
				if (_CellSize > 0) { 
					float2 steppedUV = round(i.uv / _CellSize)*_CellSize; 
					finalColor = tex2D(_MainTex, steppedUV);
				}
				else finalColor = tex2D(_MainTex, i.uv);
				
				return finalColor;
			}
			ENDCG
		}
	}
	FallBack "Diffuse"
}

Ya es tarea de ustedes hacer el script que mueve el parámetro de _Cellsize


Siento decepcionarlos al usar un título clickbait, pero yo también necesito las visitas para vivir, al menos no se fueron con las manos vacías, este fue un tema corto, para no abusar de su tiempo.


Para los que me conocen, saben que yo acostumbro hacer estos pequeños tutoriales, porque considero que los tutoriales densos, te generan lagunas y no te queda casi nada en la mente.


4 visualizaciones0 comentarios

Comentarios


bottom of page