从对象空间到世界空间的转变
如果一个对象被直接放入世界空间中,游戏对象会通过转换组件直接将对象的坐标转成世界坐标。你可以在 Scene 视图或者 Hierarchy 视图中选中一个对象,然后在 Inspector 视图中查看 Transform 组件。在 Transform 组件中包括 Position、Rotation 和 Scale 属性,这个组件用来指定从本地坐标到世界坐标的顶点转换(如果一个游戏对象拥有父级对象,那么转换组件只转换父级对象的坐标)。在《Vertex Transformations》章节中,我们将讨论顶点的转换、旋转、缩放以及 4 x 4 矩阵组合变换的细节。
(资料图片仅供参考)
回到我们的例子中:从对象空间到世界空间的转换是通过 4 x 4 矩阵来转换的,也叫“模型矩阵”,这个矩阵在 Unity 中通过 uniform 参数 _Object2World 已经声明了:
Shader "Custom/World Space"
{ SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag //uniform flaot4*4 Object3World //automatic definition of a Unity-specific uniform parameter 自动定义统一值是unity的一个特性 struct vertexOutput { float4 pos: SV_POSITION; float4 position_in_world_space : TEXCOORD0; }; vertexOutput vert(float4 vertex:POSITION) { vertexOutput output; output.pos = mul(UNITY_MATRIX_MVP,vertex); output.position_in_world_space = mul(_Object2World,vertex);//物体坐标转化为世界坐标 return output; } float4 frag(vertexOutput input) :COLOR { float dist = distance(input.position_in_world_space,float4(0.0,0.0,0.0,1.0)); //计算片段位置与原点距离(第四个坐标永远是1) if (dist < 5.0) { return float4(0.0, 1.0, 0.0, 1.0); //接近 } else return float4(0.3,0.3,0.3,1.0);//远离原点 } ENDCG } }
}
更多的 Unity Uniforms
在 Unity 中,定义了几个和 _Object2World 一样的 float4x4 矩阵,下面是在系列教程中使用的 uniforms 简短列表:
uniform float4 _Time, _SinTime, _CosTime; // time valuesuniform float4 _ProjectionParams;// x = 1 or -1 (-1 if projection is flipped)// y = near plane; z = far plane; w = 1/far planeuniform float4 _ScreenParams; // x = width; y = height; z = 1 + 1/width; w = 1 + 1/heightuniform float4 unity_Scale; // w = 1/scale; see _World2Objectuniform float3 _WorldSpaceCameraPos;uniform float4x4 _Object2World; // model matrixuniform float4x4 _World2Object; // inverse model matrix // (all but the bottom-right element have to be scaled // with unity_Scale.w if scaling is important) uniform float4 _LightPositionRange; // xyz = pos, w = 1/rangeuniform float4 _WorldSpaceLightPos0; // position or direction of light sourceuniform float4x4 UNITY_MATRIX_MVP; // model view projection matrix uniform float4x4 UNITY_MATRIX_MV; // model view matrixuniform float4x4 UNITY_MATRIX_V; // view matrixuniform float4x4 UNITY_MATRIX_P; // projection matrixuniform float4x4 UNITY_MATRIX_VP; // view projection matrixuniform float4x4 UNITY_MATRIX_T_MV; // transpose of model view matrixuniform float4x4 UNITY_MATRIX_IT_MV; // transpose of the inverse model view matrixuniform float4x4 UNITY_MATRIX_TEXTURE0; // texture matrixuniform float4x4 UNITY_MATRIX_TEXTURE1; // texture matrixuniform float4x4 UNITY_MATRIX_TEXTURE2; // texture matrixuniform float4x4 UNITY_MATRIX_TEXTURE3; // texture matrixuniform float4 UNITY_LIGHTMODEL_AMBIENT; // ambient color
用户指定 Uniforms:着色器属性
还有一个更重要的 uniform 参数:用户自定义的 uniforms。实际上,这是 Unity 的属性,你可以认为他们是着色器的用户自定义 uniform 参数。通常一个着色器不带参数只能由编写的程序员在一些特定的程序中使用,但是如果一个着色器拥有参数并且还带有描述性的说明,那么这个着色器就可以被其他人使用,另外,如果你打算出售你的着色器,为着色器的提供参数会大大增加它的价值。
因为在 Unity 的 ShaderLab 中使用《description of shader properties 》非常不错,通过下面的例子我们来了解如何使用着色器属性,首先,我们声明一个属性,然后我们再定义一个与属性名称相同、类型相同的 uniforms 。
Shader "Cg shading in world space" { Properties { _Point ("a point in world space", Vector) = (0., 0., 0., 1.0) _DistanceNear ("threshold distance", Float) = 5.0 _ColorNear ("color near to point", Color) = (0.0, 1.0, 0.0, 1.0) _ColorFar ("color far from point", Color) = (0.3, 0.3, 0.3, 1.0) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" // defines _Object2World and _World2Object // uniforms corresponding to properties uniform float4 _Point; uniform float _DistanceNear; uniform float4 _ColorNear; uniform float4 _ColorFar; struct vertexInput { float4 vertex : POSITION; }; struct vertexOutput { float4 pos : SV_POSITION; float4 position_in_world_space : TEXCOORD0; }; vertexOutput vert(vertexInput input) { vertexOutput output; output.pos = mul(UNITY_MATRIX_MVP, input.vertex); output.position_in_world_space = mul(_Object2World, input.vertex); return output; } float4 frag(vertexOutput input) : COLOR { float dist = distance(input.position_in_world_space, _Point); // computes the distance between the fragment position // and the position _Point. if (dist < _DistanceNear) { return _ColorNear; } else { return _ColorFar; } } ENDCG } }}
使用 sharedMaterial 我们可以改变所有使用了这个材质的对象的参数,如果你只希望改变一个并使用了这个材质的对象的参数,那么你应该使用 material 。假如你设置 _Point 属性为另一个对象的位置信息,这样你只需要在 Unity 中移动这个对象就可以查看效果了,你可以复制/粘贴 下面的代码到一个 C# 脚本中:
using UnityEngine;using System.Collections;[ExecuteInEditMode]public class NewBehaviourScript : MonoBehaviour {public GameObject other;void Update(){if(other != null){GetComponent().sharedMaterial.SetVector("_Point", other.transform.position);}}}
然后我们只需要移动另一个对象(Sphere)就可以看到(Cube)颜色的变化,当小球离原点近时,如图:
当小球离原点远时,如图:
在《在着色器中调试》章节中提到,顶点输入参数使用语义词 POSITION 指定对象的坐标,即本地对象(模型)的网格空间坐标,对象空间(对象的坐标系统)是特定于每个游戏对象的,然而,所有的游戏对象会被转换到一个共同的坐标系中(世界空间)。
今年煤炭增产不低于5%、将达1365亿吨,同时还要兼顾双碳。1月31日,能源大省山西开年即聚焦能源增产保供。 在2023年山西能源工作会上,更多
2023-02-01 10:54:02国家统计局31日发布消息,2022年,规模以上工业企业实现营业收入13791万亿元,比上年增长59%;发生营业成本11684万亿元,增长71%;营业收更多
2023-02-01 10:09:55中国神华1月30日晚间发布业绩预告,公司预计2022年度实现归属于本公司股东的净利润为687亿元至707亿元,同比增长366%至406%。 预计2022更多
2023-02-01 09:56:57冀中能源1月31日发布业绩预告,公司预计2022年实现归属于上市公司股东的净利润422亿至495亿元,同比增长5405%-8070%。扣非后净利润比上年更多
2023-02-01 10:03:54今年春节,冷空气强势来袭。大年初一早晨,漠河阿木尔镇劲涛气象站监测到零下53摄氏度的气温,低于1969年2月13日漠河气象站的监测数据,打更多
2023-02-01 10:10:04国家统计局近日发布的数据显示,2022年,全国规模以上工业发电量84万亿千瓦时,比上年增长22%。其中,火电增长09%;水电、核电、风电和太更多
2023-02-01 09:53:56近日,贵州省人民政府办公厅印发2023年《政府工作报告》重点工作责任分工方案,并提出把发展工业作为首要任务,加快建设现代化产业体系。更多
2023-01-31 10:09:30日前,山西省应急管理厅、国家矿山安全监察局山西局联合下发《关于进一步加强复采矿井安全生产工作的通知》,要求各级各部门紧盯春节复产更多
2023-01-31 09:59:43据天津市市场运行监测数据显示,1月份第三周(1月16日-1月22日),天津市煤炭均价为734元吨,环比持平。上周出现了旺季煤价的逆季节下跌,更多
2023-01-31 10:12:36据山西省商务厅生产资料市场监测数据显示,1月第三周(1月16日-22日),山西省煤炭均价131652元吨,环比上涨04%。其中,动力煤发热量5000-更多
2023-01-31 10:02:30