Skip to content

Instantly share code, notes, and snippets.

@JeOam
Created September 23, 2018 04:46
Show Gist options
  • Save JeOam/30efe6861a78ed23ef0e6252cb82fb9b to your computer and use it in GitHub Desktop.
Save JeOam/30efe6861a78ed23ef0e6252cb82fb9b to your computer and use it in GitHub Desktop.
Unity Shader Notes
@JeOam
Copy link
Author

JeOam commented Sep 23, 2018

screen shot 2018-09-23 at 12 46 46

@JeOam
Copy link
Author

JeOam commented Sep 23, 2018

Property types Description
Range(min, max) This creates a float property as a slider from the minimum value to the maximum value
Color This creates a color swatch in the Inspector tab that opens up a color picker = (float, float, float, float)
2D This creates a texture swatch that allows a user to drag a texture into the shader
Rect This creates a non-power of two texture swatch and function the same as the 2D GUI element
Cute This creates a cube map swatch in the Inspecter tab and allowa a user to drag and drop a cube map into the shader
float This creates a float value in the Inspector tab but without a slider
Vector This creates a four-float property that allows you to create directions or colors
Properties {
	_Color ("Color", Color) = (1,1,1,1)
	_Glossiness ("Smoothness", Range(0,1)) = 0.5
	_MyTexture ("My 2D Texture", 2D) = "defaulttexture" {}
	_MyRect ("My Rect", Rect) = "" {}
	_MyCube ("My Cube", Cube) = "defaulttexture" {}
	_MyFloat ("My Float", Float) = 0.0
    _MyInt ("My Int", Int) = 0
    _MyVector ("My Vector", Vector) = (1,1,1,1)
}

@JeOam
Copy link
Author

JeOam commented Sep 23, 2018

Shaderlab 提供的类型最终会映射成 CG 等语言变量类型,他们的映射关系为:

  • Color 和 Vector 对应为 float4, half4 或者 fixed4 类型
  • Range 和 Float 对应为 float, half, fixed 类型
  • Int 对应为 int 类型
  • 2D 对应为 sampler2D 类型
  • Cube 对应为 samplerCUBE 类型
  • 3D 对应为 sampler3D 类型

@JeOam
Copy link
Author

JeOam commented Sep 23, 2018

screen shot 2018-09-24 at 01 02 02

Different lighting models have different SurfaceOutput structs:

Type of Shaders Standard Physically-Based Lighting Models
Diffuse Any Surface Shader: SurfaceOutput Standard: SurfaceOutputStandard
Specular Any Surface Shader: SurfaceOutput Standard(Specular setup): SurfaceOutputStandardSpecular

The SurfaceOutput struct has the following properties:

  • fixed3 Albedo: This is the diffuse color of the material
  • fixed3 Normal: This is the tangent space, normal, if written
  • fixed3 Emission: This is the color of the light emitted by the material (this property is declared as half3 in the Standard Shaders)
  • fixed Alpha: This is the transparency of the material
  • half Specular: This is the specular power from 0 to 1
  • fixed Gloss: This is the specular intensity

The SurfaceOutputStandard struct has the following properties:

  • fixed3 Albedo: This is the base color of the material (whether it's diffuse or specular)
  • fixed3 Normal
  • half3 Emission: This property is declared as half3, while it was defined as fixed3 in SurfaceOutput
  • fixed Alpha
  • half Occlusion: This is the occlusion (default 1)
  • half Smoothness: This is the smoothness (0 = rough, 1 = smooth)
  • half Metallic: 0 = non-metal, 1 = metal

The SurfaceOutputStandardSpecular struct has the following properties:

  • Properties SurfaceOutputStandard had
  • fixed3 Specular: This is the specular color. This is very different from the Specular property in SurfaceOutput as it allows you to specify a color rather than a single value.

Using a Surface Shader correctly is a matter of initializing the SurfaceOutput with the correct values.

@JeOam
Copy link
Author

JeOam commented Sep 24, 2018

There are two types of variables in Cg: single values and packed arrays. The latter can be identified because their type ends with a number such as float3 or int4. As their names suggest, these types of variables are similar to structs, which means they each contain several single values. Cg calls them packed arrays, though they are not exactly arrays in the traditional sense.

The elements of a packed array can be accessed as a normal struct. They are typically called x, y, z and w. However, Cg also provides you with another alias for them, that is, r, g, b, and a.


swizzling

o.Albedo = _Color.rgb;

Albedo is fixed3, which means that it contains three values of the fixed type.
_Color is defined as a fixed4 type.


smearing

a single value is assigned a packed array, it is copied to all of fieds:

o.Albedo = 0;  // Black = (0, 0, 0)
o.Albedo = 1;  // white = (1, 1, 1)

masking

allowing only certain components of a packed array to be overwritten:

o.Albedo.rg = _Color.rg;

@JeOam
Copy link
Author

JeOam commented Sep 24, 2018

Packed Matrices

Cg allows types such as float4x4, which represents a maxtrix of floats with four rows and for columns. You can access a single element of the matrix using the _mRC notation, where R is the row and C is the column:

float4x4 matrix;
float first = matrix._m00;
float last = matrix._m33;

float4 firstRow = matrix[0];
// Equivalent to
float4 firstRow = matrix._m00_m01_m02_m03;

float4 diagonal = matrix._m00_m11_m22_m33;

@JeOam
Copy link
Author

JeOam commented Sep 24, 2018

Each vertex on the model can store data that shaders can access and use to determine what to dray. One of the most important pieces of information that are stored in vertices is the UV data. It consists of two coordinates, U and V, ranging from 0 to 1.

fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;

tex2D function takes a texture and UV and returns the color of the pixel at that position, and the returned color is tinted by _Color

@JeOam
Copy link
Author

JeOam commented Sep 24, 2018

_Time: This built-in variable return a variable of the float4 type, meaning that each component of this variable contians different values of time as it pertains to game time.

Unity - Manual: Built-in shader variables

@JeOam
Copy link
Author

JeOam commented Sep 26, 2018

Tags are used to add infomation about how the object is going to be rendered. Unity has provided us with some default render queues, each with a unique value that directs Unity when to draw the object to the screen.
This are built-in render queues:

Render queue Desc value
Background This render queue is rendered first. It is used for skyboxes and so on. 1000
Geometry This is the default render queue. This is used for most objects. Opaque geometry use this queue. 2000
AlphaTest 'Alpha-tested geometry uses this queue. It's different from the Geometry queue as it's more efficient to render alpha-tested objects after all the solid objects are drawn. 2450
Transparent This render queue is rendered after Geometry and AlphaTest queues in back-to-front order. Anything alpha-blended (that is, shaders that don't write to the depth buffer) should go here, for example, glass and particle effects. 3000
Overlay This render queue is meant for overlay effects. Anything rendered last should go here, for example, lens flares. 4000

@JeOam
Copy link
Author

JeOam commented Sep 26, 2018

#prama surface surf Lambert aplha:fade nolighting
  • Lambert: Use Lambertian Reflectance lighting model
  • nolighting: disable any lighting
  • alpha:face: signal to Cg that this is a Transparent Shader

@JeOam
Copy link
Author

JeOam commented Sep 27, 2018

Holographic Effect:

float4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; 
o.Albedo = c.rgb; 
float border = 1 - (abs(dot(IN.viewDir, IN.worldNormal))); 
float alpha = (border * (1 - _DotProduct) + _DotProduct); 
// viewDir 是平面的 nomal direction
// dot: 0      border: 1     alpha:  向量正
//                           _DotProduct: 0.25      alpha: 1
//                           _DotProduct: 0.75      alpha: 1
// dot: 0.5    border: 0.5   alpha:
//                           _DotProduct: 0.25      alpha: 0.625
//                           _DotProduct: 0.75      alpha: 0.875
// dot: 1      border: 0     alpha:   向量平行
//                           _DotProduct: 0.25      alpha: 0.25
//                           _DotProduct: 0.75      alpha: 0.75
o.Alpha = c.a * alpha; 

@JeOam
Copy link
Author

JeOam commented Sep 27, 2018

Blending textures:

float4 aTexData = tex2D(_ATexture, IN.uv_ATexture); 
float4 bTexData = tex2D(_GTexture, IN.uv_BTexture); 
float4 blendData = tex2D(_BlendTex, IN.uv_BlendTex); 

float4 finalColor = lerp(aTexData, bTexData, blendData.g); 

screen shot 2018-09-24 at 01 02 02

@JeOam
Copy link
Author

JeOam commented Nov 27, 2018

sampler2D myTex;
float4          myTex_ST;  // 附带的一个变量

// ...

float2 tiling = myTex_ST.xy; // 放大缩小的倍数 
float2 offset = myTex_ST.zw;  // 位移

float4 o = tex2D(myTex, i.uv * tiling + offset)
return o

@JeOam
Copy link
Author

JeOam commented Nov 27, 2018

图片变灰:由于视觉感光对 R,G, B 的敏感度不一样,所以取不同的权重。

float4 grayScale(float4 v) {
    float g = v.r * 0.299 + v.g * 0.578 + v.b * 0.114;
    return float4(g, g, g, v.a);
}

@JeOam
Copy link
Author

JeOam commented Nov 27, 2018

if (w < 0) w = 0;
if (w > 1) w = 1;
// 等于
w = clamp(w, 0, 1);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment