一、GLSL內(nèi)置變量
Unity 作為渲染引擎嚷炉,內(nèi)置了一些shader變量以及一些數(shù)據(jù)結(jié)構(gòu)申屹,方便Unity自身的一些函數(shù)計(jì)算,同時(shí)也開(kāi)放給開(kāi)發(fā)者使用独柑,我們開(kāi)發(fā)者同時(shí)也可以將這些視為某種規(guī)范和標(biāo)準(zhǔn),詳細(xì)參考UnityShaderVariables.cginc(Unity的內(nèi)置Shader可以在官網(wǎng)可以下載到)车酣。
同時(shí)Unity的文檔也對(duì)內(nèi)置變量做了說(shuō)明索绪,可以參考Built-in shader variables瑞驱。
Unity 內(nèi)置Shader 基本上通過(guò)Cg來(lái)編寫(xiě)的,所以GLSL內(nèi)置的變量比較少凳寺,主要關(guān)注UnityCG.glslinc和GLSLSupport.glslinc彤侍。
首先來(lái)看看UnityCG.glslinc
Unity引擎會(huì)在cpu提交gpu渲染請(qǐng)求時(shí)為這些變量賦值盏阶,開(kāi)發(fā)者只需要知道如何使用即可。
再看GLSLSupport.glslinc
這里主要看gl_前綴的變量:
變量名 | 類型 | 值 |
---|---|---|
gl_ModelViewProjectionMatrix | mat4 | MVP矩陣魄眉,將對(duì)象空間中的頂點(diǎn)轉(zhuǎn)換到裁剪空間 |
gl_ModelViewMatrix | mat4 | MV矩陣闷袒,將對(duì)象空間中的頂點(diǎn)轉(zhuǎn)換到相機(jī)空間 |
gl_ModelViewMatrixTranspose | mat4 | MV矩陣的轉(zhuǎn)置 |
gl_ModelViewMatrixInverseTranspose | mat4 | MV矩陣逆的轉(zhuǎn)置 |
gl_NormalMatrix | mat4 | 法線矩陣,將對(duì)象空間中的法線轉(zhuǎn)換到世界空間 |
gl_ProjectionMatrix | mat4 | 投影矩陣脾歇,將相機(jī)空間的頂點(diǎn)轉(zhuǎn)換到裁剪空間 |
另外還有
變量名 | 類型 | 值 |
---|---|---|
gl_Vertex | vec4 | 對(duì)象空間的頂點(diǎn)坐標(biāo) |
gl_Position | vec4 | 頂點(diǎn)著色器的輸出到片元著色器的位置(裁剪空間) |
gl_FragColor | vec4 | 最終輸出到屏幕像素的顏色值 |
gl_Normal | vec4 | 頂點(diǎn)法線 |
gl_MultiTexCoord0 | vec4 | uv |
這些是OpenGLES預(yù)定義的變量(未確認(rèn),Unity 內(nèi)置shader源碼搜索不到定義池摧,知道的大佬告知一聲),可以直接使用膘魄。
二竭讳、shading in world space
Shader "GLSL/GLSL 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) = (1.0, 0.0, 0.0, 1.0)
}
SubShader {
Pass {
GLSLPROGRAM
// uniforms corresponding to properties
uniform vec4 _Point;
uniform float _DistanceNear;
uniform vec4 _ColorNear;
uniform vec4 _ColorFar;
#include "UnityCG.glslinc"
out vec4 position_in_world_space;
#ifdef VERTEX
void main()
{
position_in_world_space = unity_ObjectToWorld * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
#endif
#ifdef FRAGMENT
void main()
{
float dist= distance(position_in_world_space, _Point);
if (dist < _DistanceNear)
{
gl_FragColor = _ColorNear;
}
else
{
gl_FragColor = _ColorFar;
}
}
#endif
ENDGLSL
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class InWorldSpace : MonoBehaviour
{
public MeshRenderer meshRenderer;
// Start is called before the first frame update
void Start()
{
if (Application.isPlaying)
{
meshRenderer.material.SetVector("_Point", new Vector4(1.0f, 0.0f, 0.0f, 1.0f));
meshRenderer.material.SetFloat("_DistanceNear", 10.0f);
meshRenderer.material.SetColor("_ColorNear", new Color(1.0f, 0.0f, 0.0f));
meshRenderer.material.SetColor("_ColorFar", new Color(0.0f, 0.0f, 1.0f));
}
else
{
meshRenderer.sharedMaterial.SetVector("_Point", new Vector4(1.0f, 0.0f, 0.0f, 1.0f));
meshRenderer.sharedMaterial.SetFloat("_DistanceNear", 10.0f);
meshRenderer.sharedMaterial.SetColor("_ColorNear", new Color(1.0f, 0.0f, 0.0f));
meshRenderer.sharedMaterial.SetColor("_ColorFar", new Color(0.0f, 0.0f, 1.0f));
}
}
// Update is called once per frame
void Update()
{
if (Application.isPlaying)
{
meshRenderer.material.SetVector("_Point", this.transform.position); // set the shader property
}
else
{
meshRenderer.sharedMaterial.SetVector("_Point", this.transform.position); // set the shader property
}
}
}