Trong trò chơi của tôi, tôi cần tạo ra những vũng nước động nhưng tôi không thể tìm thấy một hướng dẫn cho thấy cách tôi có thể tạo ra hiệu ứng như vậy (một ví dụ được trình bày bên dưới). Tôi làm nó như thế nào?
Trong trò chơi của tôi, tôi cần tạo ra những vũng nước động nhưng tôi không thể tìm thấy một hướng dẫn cho thấy cách tôi có thể tạo ra hiệu ứng như vậy (một ví dụ được trình bày bên dưới). Tôi làm nó như thế nào?
Câu trả lời:
Để tạo một shader ướt, trước tiên bạn cần phải có một sự phản chiếu.
Bạn có thể sử dụng Đầu dò phản xạ hoặc MirrorReflection3 nhưng, tôi sử dụng phản xạ giả (Bản đồ khối) ở đây vì trình tạo bóng sau đó có thể được sử dụng trên thiết bị di động.
Shader "Smkgames/TransparentCubeMap" {
Properties {
_Color("Color",Color) = (1,1,1,1)
_Cube ("Cubemap", CUBE) = "" {}
_Metallic("Metallic",Range(0,1)) = 1
_Smoothness("Smoothness",Range(0,1)) = 1
_Alpha("Alpha",Range(0,1)) = 1
}
SubShader {
Tags {"RenderType"="Transparent" "Queue"="Transparent"}
LOD 200
Pass {
ColorMask 0
}
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
CGPROGRAM
#pragma surface surf Standard fullforwardshadows alpha:fade
struct Input {
float2 uv_MainTex;
float3 worldRefl;
};
sampler2D _MainTex;
samplerCUBE _Cube;
float4 _Color;
float _Metallic;
float _Smoothness;
float4 _EmissionColor;
float _Alpha;
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb * 0.5 * _Color;
o.Emission = texCUBE (_Cube, IN.worldRefl).rgb*_Color;
o.Metallic = _Metallic;
o.Smoothness = _Smoothness;
o.Alpha = _Alpha;
}
ENDCG
}
Fallback "Diffuse"
}
Để thêm méo vào hình phản chiếu của bạn, bạn có thể nhân bản đồ bình thường và worldRefl
:
float3 distortion = tex2D(_Distortion, IN.uv_Distortion);
o.Emission = texCUBE(_Cube, IN.worldRefl*distortion).rgb
Bạn có thể sử dụng tiếng ồn để tạo hình dạng thủ tục :
Dưới đây là hướng dẫn Fractal Brownian Motion (FBM) .
Shader "Smkgames/FbmNoise"
{
Properties
{
_TileAndOffset("Tile and Offset",Vector) = (1,1,0,0)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
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.com
float 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/4dS3Wd
float noise (in float2 st) {
float2 i = floor(st);
float2 f = frac(st);
// Four corners in 2D of a tile
float 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 6
float fbm (in float2 st) {
// Initial values
float value = 0.0;
float amplitude = .5;
float frequency = 0.;
//
// Loop of octaves
for (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
}
}
}
FBM ở trên không nên được sử dụng trực tiếp vào trình đổ bóng của bạn vì nó có nhiều tính toán GPU và giảm hiệu suất. Thay vì sử dụng trực tiếp, bạn có thể hiển thị kết quả thành một kết cấu với RenderTexture .
Shadertoy sử dụng nhiều đường chuyền , mỗi lần "đệm". Như tên cho thấy, pass này lưu trữ các kết quả trong một bộ đệm, đây chỉ là một kết cấu. Unity sẽ cho phép bạn kết xuất với kết cấu quá.
Bạn có thể làm một mặt nạ dày và mịn với các chức năng sau:
Đầu ra 1 nếu [A]
nhỏ hơn hoặc bằng [B]
, nếu không thì xuất 0.
Pha trộn trơn tru giữa hai giá trị, dựa trên vị trí của giá trị thứ ba trong phạm vi đó, xuất ra các giá trị trong khoảng từ 0 đến 1. Hãy nghĩ về nó như một lerp nghịch đảo kẹp với giá trị đầu ra được làm mịn.
/* 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 Kamaly
Shader "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 200
Pass{
ColorMask 0
}
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
CGPROGRAM
#pragma surface surf Standard fullforwardshadows alpha:fade
struct Input {
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;
static const 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"
}
Đây là một định nghĩa hữu ích:
Roughness Mô tả microsurface của đối tượng. Trắng 1.0 thô và đen 0,0 mịn. Mặt kính hiển vi nếu thô có thể làm cho các tia sáng tán xạ và làm cho phần nổi bật trông mờ hơn và rộng hơn. Cùng một lượng năng lượng ánh sáng được phản xạ đi ra ngoài bề mặt. Bản đồ này có sự tự do nghệ thuật nhất. Không có câu trả lời sai ở đây. Bản đồ này mang lại cho tài sản nhiều đặc tính nhất vì nó thực sự mô tả bề mặt, ví dụ như vết trầy xước, dấu vân tay, vết bẩn, bụi bẩn, v.v.
Độ bóng Bản đồ này là nghịch đảo của bản đồ độ nhám. Trắng 1.0 mịn và 0,0 đen là thô. Mô tả microsurface của đối tượng. Mặt kính hiển vi nếu thô có thể làm cho các tia sáng tán xạ và làm cho phần nổi bật trông mờ hơn và rộng hơn. Cùng một lượng năng lượng ánh sáng được phản xạ đi ra ngoài bề mặt. Bản đồ này có sự tự do nghệ thuật nhất. Không có câu trả lời sai ở đây. Bản đồ này mang lại cho tài sản nhiều đặc tính nhất vì nó thực sự mô tả bề mặt, ví dụ như vết trầy xước, dấu vân tay, vết bẩn, bụi bẩn, v.v.
Specular Bản đồ này chứa thông tin phản xạ cho cả bề mặt kim loại và điện môi (phi kim loại). Đây là một sự khác biệt chính trong quy trình công việc kim loại / thô và spec / độ bóng. Các quy tắc tương tự áp dụng. Bạn cần sử dụng các giá trị đo cho kim loại và hầu hết tất cả các chất điện môi sẽ nằm trong phạm vi 0,04 - 4%. Nếu có bụi bẩn trên kim loại, giá trị phản xạ cũng cần phải được hạ xuống. Tuy nhiên, bạn có thể thêm các giá trị khác nhau trong bản đồ đặc trưng cho vật liệu điện môi vì bạn có quyền kiểm soát tác giả bản đồ.
Tôi không biết tại sao, nhưng trình tạo bóng tiêu chuẩn Unity không có bản đồ độ mịn, vì vậy tôi đã viết một trình tạo bóng cơ bản và thêm bản đồ này.
Shader "Smkgames/SimpleSurface" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_GlossMap("GlossMap",2D) = "white"{}
_Glossiness ("Smoothness", Float) = 1.5
_Metallic ("Metallic", Float) = 0.5
_MetallicMap("MetallicMap",2D) = "white"{}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness,_Metallic;
fixed4 _Color;
sampler2D _GlossMap,_MetallicMap;
UNITY_INSTANCING_CBUFFER_START(Props)
UNITY_INSTANCING_CBUFFER_END
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic*tex2D(_MetallicMap,IN.uv_MainTex);
o.Smoothness = _Glossiness*tex2D(_GlossMap,IN.uv_MainTex);
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Tôi nghĩ Unity không có độ nhám, nó chỉ có kim loại, nhưng kênh alpha dành cho độ nhám và kênh màu đỏ là dành cho kim loại. Bạn có thể thay đổi cường độ với độ mịn.
https://80.lv/articles/how-to-create-wet-mud-in-substance-designer/