我在Unity中有一个场景:
-
一个空的游戏对象,我们称之为“ Center ”
-
由着色器投影到球面上(以 Center 为球体中心)的网格
它工作正常 . 我试图添加基于 center -> vertex 的3dnoise(我们称之为“ direction ”) . 它工作正常 . 现在我正在尝试使用基于 direction 的相同3dnoise,但相对于 Center 方向 . Unity有一个名为transform.WorldToLocalMatrix的功能(在C#中运行良好),但由于's not possible to pass matrices as properties in Unity shaders, I' ve已将其作为四个分隔的* Vector4 * s传递:
void Update() {
terrainMaterial.SetVector("_Center", transform.position);
terrainMaterial.SetVector("_Matrix1", new Vector4(transform.worldToLocalMatrix.m00, transform.worldToLocalMatrix.m01, transform.worldToLocalMatrix.m02, 0.0f));
terrainMaterial.SetVector("_Matrix2", new Vector4(transform.worldToLocalMatrix.m10, transform.worldToLocalMatrix.m11, transform.worldToLocalMatrix.m12, 0.0f));
terrainMaterial.SetVector("_Matrix3", new Vector4(transform.worldToLocalMatrix.m20, transform.worldToLocalMatrix.m21, transform.worldToLocalMatrix.m22, 0.0f));
terrainMaterial.SetVector("_Matrix4", new Vector4(0.0f, 0.0f, 0.0f, 0.0f));
}
然后,在着色器中:
Shader "Custom/testShader"
{属性{_ Color(“颜色”,颜色)=(1,1,1,1)_MainTex(“Albedo(RGB)”,2D)=“white”{} _Glossiness(“Smoothness”,Range(0,1) )= 0.5 _金属(“金属”,范围(0,1))= 0.0
_Center("Center of the Planet", Vector) = (0.0, 0.0, 0.0)
_Matrix1("1", Vector) = (0.0, 0.0, 0.0, 0.0)
_Matrix2("2", Vector) = (0.0, 0.0, 0.0, 0.0)
_Matrix3("3", Vector) = (0.0, 0.0, 0.0, 0.0)
_Matrix4("4", Vector) = (0.0, 0.0, 0.0, 0.0)
_Scale("Scale of Noise", Range(0.001, 200.0)) = 1.0
_Height("Height of Noise", Range(1.0, 500.0)) = 5.0
}
SubShader
{
Tags{ "RenderType" = "Opaque" }
CGPROGRAM
#pragma target 3.0
#pragma surface surf Standard vertex:vert
#include "libs/noiseSimplex.cginc"
sampler2D _MainTex;
half _Glossiness;
half _Metallic;
fixed4 _Color;
float3 _Center;
float4 _Matrix1;
float4 _Matrix2;
float4 _Matrix3;
float4 _Matrix4;
float _Scale;
float _Height;
struct Input {
float2 uv_MainTex;
};
void vert(inout appdata_full v)
{
float3 direction = mul(unity_ObjectToWorld, v.vertex) - _Center;
float4x4 worldToLocal_matrix = (_Matrix1.x, _Matrix1.y, _Matrix1.z, _Matrix1.w,
_Matrix2.x, _Matrix2.y, _Matrix2.z, _Matrix2.w,
_Matrix3.x, _Matrix3.y, _Matrix3.z, _Matrix3.w,
_Matrix4.x, _Matrix4.y, _Matrix4.z, _Matrix4.w);
float3 local_direction = mul(worldToLocal_matrix, direction);
direction = _Center + normalize(direction) * (_Radius + snoise(local_direction * _Scale) * _Height);
v.vertex = mul(unity_WorldToObject, float4(direction, 1));
}
void surf(Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Diffuse"
}
我根本不理解的是......在不改变任何其他内容的情况下,这条线有效:
direction = _Center + normalize(direction) * (_Radius + snoise(direction * _Scale) * _Height);
这个没有:
direction = _Center + normalize(direction) * (_Radius + snoise(local_direction * _Scale) * _Height);
关于我做错了什么的任何想法?
1 回答
RESOLVED:
通过SetMatrix()传递WorldToLocalMatrix很好,但是分割它并在着色器中重建是行不通的 . 我糊涂了