¿Cómo puedo hacer un sombreador de "superficie húmeda" / "charco poco profundo" en Unity?
71
En mi juego, necesito crear charcos de agua dinámicos, pero no puedo encontrar un tutorial que muestre cómo puedo hacer ese efecto (un ejemplo del cual se muestra a continuación). ¿Cómo puedo hacerlo?
Molesto de ver una pregunta tan votada y una respuesta votada más alta no se cierra. Está bien elegir tu propia respuesta como mejor, aunque un poco tonto para reclamar la recompensa por ti mismo :)
Tim Holt
@TimHolt ¿Sobre qué base cerraríamos una pregunta como esta? Parece perfectamente sobre el tema.
Josh
Estoy diciendo que la persona que lo preguntó debería aceptar su propia respuesta. Perdón por mi mal uso del inglés.
Tim Holt
Respuestas:
121
Reflexión
Para crear un sombreador húmedo, primero debe tener un reflejo.
Puede usar una Sonda de reflexión o una Reflexión de espejo3 pero, aquí uso una reflexión falsa (Mapa de cubos) porque el sombreador se puede usar en dispositivos móviles.
Shader"Smkgames/FbmNoise"{Properties{_TileAndOffset("Tile and Offset",Vector)=(1,1,0,0)}SubShader{Tags{"RenderType"="Opaque"}
LOD 100Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work#pragma multi_compile_fog
#include"UnityCG.cginc"struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;};struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;};
float4 _TileAndOffset;float_Step,_Min,_Ma;
v2f vert (appdata v){
v2f o;
o.vertex =UnityObjectToClipPos(v.vertex);
o.uv = v.uv*_TileAndOffset.xy+_TileAndOffset.zw;
UNITY_TRANSFER_FOG(o,o.vertex);return o;}// Author @patriciogv - 2015// http://patriciogonzalezvivo.comfloat random (in float2 st){return frac(sin(dot(st.xy,
float2(12.9898,78.233)))*43758.5453123);}// Based on Morgan McGuire @morgan3d// https://www.shadertoy.com/view/4dS3Wdfloat noise (in float2 st){
float2 i = floor(st);
float2 f = frac(st);// Four corners in 2D of a tilefloat a = random(i);float b = random(i + float2(1.0,0.0));float c = random(i + float2(0.0,1.0));float d = random(i + float2(1.0,1.0));
float2 u = f * f *(3.0-2.0* f);return lerp(a, b, u.x)+(c - a)* u.y *(1.0- u.x)+(d - b)* u.x * u.y;}#define OCTAVES 6float fbm (in float2 st){// Initial valuesfloat value =0.0;float amplitude =.5;float frequency =0.;//// Loop of octavesfor(int i =0; i < OCTAVES; i++){
value += amplitude * noise(st);
st *=2.;
amplitude *=.5;}return value;}
fixed4 frag (v2f i): SV_Target
{
float2 st =i.uv;
float3 color = float3(0,0,0);
color += fbm(st*3.0);return float4(color,1.0);}
ENDCG
}}}
El FBM anterior no debe usarse directamente en su sombreador porque tiene muchos cálculos de GPU y disminuye el rendimiento. En lugar de usar directamente, puede renderizar el resultado a una textura con RenderTexture .
Shadertoy utiliza múltiples pases , uno por "buffer". Como su nombre indica, este pase almacena los resultados en un búfer, que es solo una textura. La unidad también te permitirá renderizar texturas.
Creando máscara
Puede hacer una máscara gruesa y suave con estas funciones:
Se mezcla suavemente entre dos valores, en función de dónde se encuentra un tercer valor en ese rango, generando valores entre 0 y 1. Piense en ello como un lerp inverso fijo con un valor de salida suavizado.
Resultado
/* Warning: don't use this shader because this is for preview only.
It has many GPU calculations so if you want use this in your game you should
remove the FBM noise functions or render it to texture, or you can use an FBM texture
*///Created By Seyed Morteza KamalyShader"Smkgames/WetShader"{Properties{_MainTex("MainTex",2D)="white"{}_Distortion("Distortion",2D)="bump"{}_Cube("Cubemap", CUBE)=""{}_BumpMap("Bumpmap",2D)="bump"{}_Metallic("Metallic",Range(0,1))=0_Smoothness("Smoothness",Range(0,1))=1_ReflectAlpha("ReflectAlpha",Range(0,1))=1
scaleX("UV.X scale",Float)=10.0
scaleY("UV.Y scale",Float)=10.0_Smooth("Smooth",Float)=0.4_Intensity("Intensity",Float)=1}SubShader{Tags{"RenderType"="Transparent""Queue"="Transparent"}
LOD 200Pass{ColorMask0}ZWriteOffBlendSrcAlphaOneMinusSrcAlphaColorMask RGB
CGPROGRAM
#pragma surface surf Standard fullforwardshadows alpha:fade
structInput{
float2 uv_MainTex;
float2 uv_Distortion;
float3 worldRefl;
float2 uv_BumpMap;
INTERNAL_DATA
};
sampler2D _MainTex,_Distortion;
samplerCUBE _Cube;float_Metallic,_Smoothness;
float4 _EmissionColor;
sampler2D _NormalMap;
uniform fixed scaleX, scaleY,_Smooth,_Intensity,_Alpha,_ReflectAlpha;staticconst float2x2 m = float2x2(-0.5,0.8,1.7,0.2);float hash(float2 n){return frac(sin(dot(n, float2(95.43583,93.323197)))*65536.32);}float noise(float2 p){
float2 i = floor(p);
float2 u = frac(p);
u = u*u*(3.0-2.0*u);
float2 d = float2 (1.0,0.0);float r = lerp(lerp(hash(i), hash(i + d.xy), u.x), lerp(hash(i + d.yx), hash(i + d.xx), u.x), u.y);return r*r;}float fbm(float2 p){float f =0.0;
f +=0.500000*(0.5+0.5*noise(p));return f;}float fbm2(float2 p){float f =0.0;
f +=0.500000*(0.6+0.45*noise(p)); p = p*2.02; p = mul(p, m);
f +=0.250000*(0.6+0.36*noise(p));return f;}void surf(Input IN, inout SurfaceOutputStandard o){
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Metallic=_Metallic;
o.Smoothness=_Smoothness;
o.Alpha=1;float t = fbm2(float2(IN.uv_MainTex.x*scaleX, IN.uv_MainTex.y*scaleY));float fbmMask = step(t,_Smooth)*_Intensity;
float3 distortion = tex2D(_Distortion, IN.uv_Distortion);
o.Emission= texCUBE(_Cube, IN.worldRefl*distortion).rgb*_ReflectAlpha*fbmMask;
o.Albedo= float4(1.0,1.0,1.0,1.0)*tex2Dlod(_MainTex, float4(IN.uv_MainTex,0.0,0.0));}
ENDCG
}Fallback"Diffuse"}
Rugosidad
Describe la micro-superficie del objeto. El blanco 1.0 es rugoso y el negro 0.0 es suave. La micro-superficie, si es rugosa, puede hacer que los rayos de luz se dispersen y que el resaltado parezca más tenue y más amplio. La misma cantidad de energía luminosa se refleja al salir a la superficie. Este mapa tiene la mayor libertad artística. No hay respuestas incorrectas aquí. Este mapa le da al activo el mayor carácter, ya que realmente describe la superficie, por ejemplo, rasguños, huellas digitales, manchas, mugre, etc.
Brillo
Este mapa es el inverso del mapa de rugosidad. El blanco 1.0 es suave y el negro 0.0 es rugoso. Describe la micro-superficie del objeto. La micro-superficie, si es rugosa, puede hacer que los rayos de luz se dispersen y que el resaltado parezca más tenue y más amplio. La misma cantidad de energía luminosa se refleja al salir a la superficie. Este mapa tiene la mayor libertad artística. No hay respuestas incorrectas aquí. Este mapa le da al activo el mayor carácter, ya que realmente describe la superficie, por ejemplo, rasguños, huellas dactilares, manchas, mugre, etc.
Especular
Este mapa contiene la información de reflectancia para superficies metálicas y dieléctricas (no metálicas). Esta es una diferencia clave en los flujos de trabajo metal / rugoso y spec / gloss. Se aplican las mismas reglas. Debe usar valores medidos para metales y la mayoría de todos los dieléctricos caerán con el rango de 0.04 - 4%. Si hay suciedad en el metal, el valor de reflectancia también debe reducirse. Sin embargo, puede agregar diferentes valores en el mapa especular para materiales dieléctricos ya que tiene el control para crear el mapa.
Creo que Unity no tiene rugosidad, solo tiene metal, pero el canal alfa es para rugosidad y el canal rojo es para metálico. Puedes cambiar la intensidad con suavidad.
Wow, has hecho una serie completa de tutoriales sobre sombreadores en el sitio de preguntas y respuestas.
Ocelot
66
@Ocelot Me encanta cómo Seyed sigue agregando más y más de estos aquí. Me gusta jugar con sombreadores y estos son realmente útiles para obtener más ideas y también como tutoriales. Él puede seguir publicando estos para siempre en mi opinión.
John Hamilton
77
Respuesta asombrosa Es muy difícil trabajar con los sombreadores y me lleva horas de violín, investigación, prueba y error, y el examen de otros sombreadores para obtener los efectos que quiero. Y aquí estás haciendo eso, para otra persona, gratis.
Draco18s el
1
Para los materiales estándar, generalmente es mejor incrustar la rugosidad en el mapa metálico o normal (el primero parece ser el predeterminado). Recomendaría usar Photo Shop, Paint Shop o Gimp para crear un metal adecuado que incruste la aspereza. Alternativamente, si tiene Substance Painter o similar, puede exportar su aspereza exactamente como Unity los desea y tener la ventaja de visualizar sus materiales antes de ponerlos en Unity.
Respuestas:
Reflexión
Para crear un sombreador húmedo, primero debe tener un reflejo.
Puede usar una Sonda de reflexión o una Reflexión de espejo3 pero, aquí uso una reflexión falsa (Mapa de cubos) porque el sombreador se puede usar en dispositivos móviles.
Distorsión
Para agregar distorsión a su reflejo, puede multiplicar el mapa normal y el
worldRefl
:Forma procesal
Puede usar el ruido para crear una forma de procedimiento :
Aquí hay un tutorial de Fractal Brownian Motion (FBM) .
El FBM anterior no debe usarse directamente en su sombreador porque tiene muchos cálculos de GPU y disminuye el rendimiento. En lugar de usar directamente, puede renderizar el resultado a una textura con RenderTexture .
Shadertoy utiliza múltiples pases , uno por "buffer". Como su nombre indica, este pase almacena los resultados en un búfer, que es solo una textura. La unidad también te permitirá renderizar texturas.
Creando máscara
Puede hacer una máscara gruesa y suave con estas funciones:
Paso
Emite 1 si
[A]
es menor o igual que[B]
, de lo contrario, emite 0.Smoothstep
Se mezcla suavemente entre dos valores, en función de dónde se encuentra un tercer valor en ese rango, generando valores entre 0 y 1. Piense en ello como un lerp inverso fijo con un valor de salida suavizado.
Resultado
Usar mapas
Sombreado basado físicamente
Aquí hay algunas definiciones útiles:
Aspereza
No sé por qué, pero el sombreador estándar de Unity no tiene un mapa de suavidad, así que escribí un sombreador básico y agregué este mapa.
Creo que Unity no tiene rugosidad, solo tiene metal, pero el canal alfa es para rugosidad y el canal rojo es para metálico. Puedes cambiar la intensidad con suavidad.
Fuente en GitHub .
Enlaces útiles
https://80.lv/articles/how-to-create-wet-mud-in-substance-designer/
https://www.fxguide.com/featured/game-environments-partc/
fuente