Skip to content

Instantly share code, notes, and snippets.

@belzecue
Forked from sugi-cho/Uneune.shader
Created August 25, 2019 18:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save belzecue/0a867791e3c32a0c185d1107938fcbb9 to your computer and use it in GitHub Desktop.
Save belzecue/0a867791e3c32a0c185d1107938fcbb9 to your computer and use it in GitHub Desktop.
頂点をいじるシェーダーで、法線もいじる

#今日のまとめ(7/23) ##オブジェクト空間からワールド空間での各値を求める。

  • fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
  • fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
  • fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;

##ノーマルマップを貼る NormalMapは、接線座標系内の法線方向なので、ノーマルマップをオブジェクトに適応する計算は、接線座標系で行う。

#include UnityStandardInput.cginchalf3 NormalInTangentSpace(float4 texcoords)

//in vert func
  o.tSpace0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
  o.tSpace1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
  o.tSpace2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
//in frag func
  fixed3 worldN;
  worldN.x = dot(IN.tSpace0.xyz, o.Normal);
  worldN.y = dot(IN.tSpace1.xyz, o.Normal);
  worldN.z = dot(IN.tSpace2.xyz, o.Normal);
  o.Normal = worldN;

タンジェント空間でのノーマル計算したんやから、tangentToWorldのmatrixとかで、変換すれば良いだけな気がするけど、なざ、こうやってるのかは、まだ理解できてない
↑tangentToWorld Matrixは、頂点ごとに異なる!!

##UnityCG.cginc

  • #define UNITY_PI 3.14159265359f
  • unpackScaleNormal(half4 packedNormal, half bumpScale)
  • UnpackNormal()とは何なのか?UnpackNormal

##Normal normal

Shader "Custom/Uneune" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_BumpMap ("bump",2D) = "bump" {}
_VNF ("vert normal factor", Float) = 1.0
_MNF ("map normal factor", Float) = 1.0
}
CGINCLUDE
//https://github.com/keijiro/NoiseShader
#include "/Assets/CGINC/ClassicNoise3D.cginc"
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
sampler2D _BumpMap;
float _VNF,_MNF;
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
half3 tNormal; //normal in tangent space
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
//http://forum.unity3d.com/threads/sobel-operator-height-to-normal-map-on-gpu.33159/
float3 height2normal_sobel(float3x3 c){
float3x3 x = float3x3
(
1.0, 0.0, -1.0,
2.0, 0.0, -2.0,
1.0, 0.0, -1.0
);
float3x3 y = float3x3
(
1.0, 2.0, 1.0,
0.0, 0.0, 0.0,
-1.0,-2.0,-1.0
);
x = x * c;
y = y * c;
float cx =
x[0][0] + x[0][2] +
x[1][0] + x[1][2] +
x[2][0] + x[2][2];
float cy =
y[0][0] + y[0][1] + y[0][2] +
y[2][0] + y[2][1] + y[2][2];
float cz =sqrt(1-(cx*cx+cy*cy));
return float3(cx, cy, cz);
}
half height(half3 pos){
return cnoise(pos) * 0.5;
}
half3x3 height3x3(half3 pos, half3 normal, half3 tangent, half d){
half3 binormal = cross(normal, tangent);
half dx = d * normalize(tangent);
half dy = d * normalize(binormal);
half3x3 h;
h[0][0] = height(pos - dx - dy);
h[0][1] = height(pos - dy);
h[0][2] = height(pos + dx - dy);
h[1][0] = height(pos - dx);
h[1][1] = height(pos);
h[1][2] = height(pos - dx);
h[2][0] = height(pos - dx + dy);
h[2][1] = height(pos + dy);
h[2][2] = height(pos + dx + dy);
return h;
}
void vert (inout appdata_full v, out Input o){
half3 pos = v.vertex.xyz*1.5 + _Time.y;
v.vertex.xyz += v.normal * height(pos);
UNITY_INITIALIZE_OUTPUT(Input,o);
half3x3 h3x3 = height3x3(pos, v.normal, v.tangent, 0.05);
o.tNormal = height2normal_sobel(h3x3);
}
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
half4 normal = tex2D (_BumpMap, IN.uv_BumpMap);
normal.xy = normal.wy*2-1;
normal.xy *= _MNF; //ノーマルマップの強さ
normal.xy += IN.tNormal.xy*_VNF; //頂点シェーダで計算した、法線変位
normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));
o.Normal = normal;
// o.Normal = UnpackScaleNormal (tex2D (_BumpMap, IN.uv_BumpMap),1.5);
o.Alpha = c.a;
}
ENDCG
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard vertex:vert addshadow
ENDCG
}
FallBack "Diffuse"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment