답변:
습식 셰이더를 만들려면 먼저 반사가 필요합니다.
리플렉션 프로브 또는 MirrorReflection3을 사용할 수 있지만 여기서는 모바일에서 셰이더를 사용할 수 있기 때문에 가짜 반사 (큐브 맵)를 사용합니다.
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"
}
반사에 왜곡을 추가하려면 노멀 맵과 worldRefl
:
float3 distortion = tex2D(_Distortion, IN.uv_Distortion);
o.Emission = texCUBE(_Cube, IN.worldRefl*distortion).rgb
노이즈를 사용하여 절차 모양 을 만들 수 있습니다 .
FBM (Fractal Brownian Motion) 자습서는 다음과 같습니다 .
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은 GPU 계산이 많고 성능이 저하되므로 셰이더에 직접 사용하면 안됩니다. 직접 사용하는 대신 RenderTexture 를 사용하여 결과를 텍스처로 렌더링 할 수 있습니다 .
Shadertoy 는 "버퍼"당 하나씩 여러 패스를 사용합니다 . 이름에서 알 수 있듯이이 패스는 결과를 버퍼에 저장합니다. 텍스처입니다. 유니티는 텍스처로도 렌더링 할 수있게 해줍니다.
다음 기능으로 두껍고 부드러운 마스크를 만들 수 있습니다.
[A]
보다 작거나 같으면 1을 출력 하고 [B]
, 그렇지 않으면 0을 출력합니다.
세 번째 값이 해당 범위 내에있는 위치를 기준으로 두 값 사이를 부드럽게 혼합하여 0과 1 사이의 값을 출력합니다.이 값을 평활 한 출력 값을 가진 클램프 된 역 레프라고 생각하십시오.
/* 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"
}
유용한 정의는 다음과 같습니다.
거칠기 개체의 미세 표면을 설명합니다. 흰색 1.0은 거칠고 검은 0.0은 매끄 럽습니다. 표면이 거칠면 광선이 산란되어 하이라이트가 더 어둡고 넓게 보일 수 있습니다. 같은 양의 빛 에너지가 표면으로 들어오는 것처럼 반사됩니다. 이지도는 가장 예술적인 자유를 가지고 있습니다. 여기에는 오답이 없습니다. 이 맵은 스크래치, 지문, 번짐, 때 등 표면을 설명 할 때 자산에 가장 특징이 있습니다.
광택 이 맵은 거칠기 맵의 반대입니다. 흰색 1.0은 매끄럽고 0.0 검정은 거칠습니다. 물체의 미세 표면을 설명합니다. 표면이 거칠면 광선이 산란되어 하이라이트가 더 어둡고 넓게 보일 수 있습니다. 같은 양의 빛 에너지가 표면에 들어올 때 반사됩니다. 이지도는 가장 예술적인 자유를 가지고 있습니다. 여기에는 오답이 없습니다. 이 맵은 스크래치, 지문, 번짐, 때 등 표면을 설명 할 때 자산에 가장 특징이 있습니다.
Specular 이 맵에는 금속 및 유전체 (비금속) 표면에 대한 반사율 정보가 포함되어 있습니다. 이는 금속 / 거칠기 및 사양 / 광택 워크 플로우의 주요 차이점입니다. 동일한 규칙이 적용됩니다. 금속에 대해 측정 된 값을 사용해야하며 대부분의 모든 유전체는 0.04-4 % 범위로 떨어집니다. 금속에 먼지가 있으면 반사도 값을 낮추어야합니다. 그러나 맵을 작성하도록 제어 할 수 있으므로 유전체 재질의 반사 맵에 다른 값을 추가 할 수 있습니다.
이유를 모르겠지만 Unity 표준 셰이더에는 매끄러움 맵이 없으므로 기본 셰이더를 작성하고이 맵을 추가했습니다.
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"
}
Unity에는 거칠기가 없으며 금속성 만 있지만 알파 채널은 거칠기, 빨간색 채널은 메탈릭입니다. 매끄럽게 강도를 변경할 수 있습니다.
https://80.lv/articles/how-to-create-wet-mud-in-substance-designer/