using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp4
{
class Program
{
static void addone(List<int> list)
{
for (int i = 0; i < list.Count; i += 2)
{
list[i] += 1;
}
}
static void classifyoddeven(List<int> list, List<int> odd, List<int> even)
{
for (int i = 0; i < list.Count; i++)
{
if (list[i] % 2 == 0)
{
even.Add(list[i]);
}
else
{
odd.Add(list[i]);
}
}
}
static void printList(List<int> li)
{
foreach (int item in li)
{
Console.Write(item + " ");
}
Console.WriteLine();
}
static void Main(string[] args)
{
List<int> list = new List<int> { 1, 2, 3, 4, 5, 6 };
List<int> odd = new List<int>();
List<int> even = new List<int>();
classifyoddeven(list, odd, even);
addone(list);
printList(list);
printList(odd);
printList(even);
}
}
}
using System;
using System.Collections.Generic;
namespace Test
{
class Program
{
static void PrintList(List<int> lst)
{
foreach(int item in lst)
{
Console.Write(item + " ");
}
Console.WriteLine();
}
static void Main()
{
List<int> list = new List<int> { 3, 6, 7, 8, 6, 6, 2, 4 };
int i = 0;
while (i< list.Count)
{
if(list[i]%2 == 0)
{
list.RemoveAt(i);
}
else
{
i++;
}
}
PrintList(list);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp4
{
class Program
{
static void PrintList(List<string> lst)
{
foreach (string item in lst)
{
Console.Write(item + " ");
}
Console.WriteLine();
}
static Random random = new Random();
public static int RandomNum(int a, int b)
{
return random.Next(a, b);
}
static void Main(string[] args)
{
List<string> ck = new List<string>();
string[] ckk = { "S", "A", "A", "B", "B", "C", "C", "C", "C" };
ck.AddRange(ckk);
//PrintList(ck);
int c = RandomNum(0,8);
Console.WriteLine(ck[c]);
}
}
}
以Unity3D为介讲解计算机图形学
以下所有文字都是小编一个字一个字敲出来的TnT
OpenGL渲染流程
Cpu:
FBX加载到内存 ->meshrender
FBX、OBJ 等模型文件:包含 uv、顶点位置、法线、切线 等渲染所需要的信息
MeshRender(skin mesh render/mesh render mesh filter) :将这些信息传递到GPU
skin mesh render:带蒙皮的骨骼
mesh render :主要是将顶点等信息传递到GPU
mesh filter:指定哪个模型
Gpu:
渲染管线:
顶点着色器 -> 光栅化 -> 片段着色器 -> alpha测试 -> 模板测试 -> 深度测试 -> 深度测试 -> Blend
-> Gbuffer ->frontBuffer ->frame buffer -> 显示器
顶点着色器:
1.计算顶点的颜色
2.顶点变换(将物体坐标系 转换到 相机坐标系)
3.灯光的作用
光栅化:
将顶点转换成像素
插值的过程
顶点 4 个 到了 片段着色器 100*100
(顶点着色器会运行4次 , 片段着色器会运行10000次)
(顶点着色器和片段着色器 运算次数 不是一个量级)
(尽量把运算放在顶点着色器中)
片段着色器:
(已经是像素点了)
1.纹理采样:从纹理像素赋给像素
2.像素跟灯光计算
Alpha测试:
挑选合格的alpha像素显示
模板测试:像素还可以携带模板信息,达到条件的模板值
深度测试:符合条件的像素就通过,不然就丢弃
Blend:
将当前要渲染的像素和已经渲染出来的像素混合
GBuffer:
RGBA 模板值 深度值 等
Float [720*1280*4]
Front Buffer:
float[720*1280]
framebuffer:
float[720*1280]
像素: RGBA四通道 RGBA888(每个通道占8bit)
屏幕:720*1280 Float [720*1280]
Shader介绍
1.shader语言
OpenGL:SGI公司 跨平台
【GLSL:opengl shader language】
DirectX:微软开发 非跨平台 性能非常好
【HLSL:high level shader lauguage】
CG:微软和英伟达 跨平台 基于C语言
2.unity shader 语言
【opengl dx cg】
CG和HLSL包括在CGPROGRAM...ENDCG语法块内
GLSL包括在GLSLPROGRAM...ENDGLSL语法块内
unity自己的语言 shader lab
3.unity shader 分类
fixed shader:shader 1.0 主要是 开关式
顶点 片段 着色器:shader 2.0 功能里面的 公式 我们可以自己定义
Surface shader
4.shader 结构注释解析
Shader "Hidden/11"
{
Properties //属性
{
_MainTex ("Texture", 2D) = "white" {}
}
//可能存在多个subshader ;unity会在所有subshader列表中选择当前环境中可 的第一个subshader
SubShader
{
//subshader的标签【Tags】
//给多个pass的公用的设置【Common State】
// No culling or depth
Cull Off ZWrite Off ZTest Always
//可能存在多个pass,每个pass都会引起一次渲染过程
Pass
{
//pass 的标签【Pass Tags】
//渲染设置,如颜色混合【Render Setup】
//纹理设置,只有在 fixed function shader 中才能使用【Texture Setup】
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
// just invert the colors
col.rgb = 1 - col.rgb;
return col;
}
ENDCG
}
//可以有多个pass
//【其他pass】
//【Fallback】
//当有自定义shader的设置UI时候用【CustomEditor】
}
}
Shader "Custom/NewSurfaceShader"
{
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
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
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;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
什么是材质球?人的衣服
什么是shader?决定材质、灯光的作用
Shader属性定义的通用格式:
Properties { Property [Property ... ] }
定义一个 int :
name("display name",Int) = number
name:变量的名字
display name:供外界 参考说明
int:表示 变量类型 = number:表示默认值
For 2D Textures,the default value is either an empty string,or one of the built-in default Texture:"white"(RGBA:1,1,1,1),"black"(RGBA:0,0,0,0),"gray"(RGBA:0.5,0.5,0.5,0.5),"bump"(RGBA:0.5,0.5,1,0.5) or "red"(RGBA:1,0,0,0).
有六个面的纹理
3D纹理:
1.只能用script创建
2.opengl 3.0 及以上才支持
Shader 1.0:
顶点着色器 -> 光栅化 -> 片段着色器 -> alpha测试 ->模板测试 ->深度测试 -> Blend -> Gbuffer ->
frontBuffer -> frame buffer -> 显示器
可编程的有:顶点着色器 片段着色器 三大测试
调节顶点的颜色:
Shader "Hidden/testvertex"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_TestColor("TestColor", Color) = (1,0,0,1)
}
SubShader
{
Pass
{
//Color (0,1,0,1)
//Color[_TestColor]
Material
{
// Diffuse(1,0,0,1)
//Diffuse[_TestColor]
//Ambient[_TestColor]
Specular[_TestColor]
}
//Lighting On
SeparateSpecular On
}
}
}
灯光计算公式
Unity - Manual: Surface Shader lighting examples (unity3d.com)
Ambient*Lighting Window's Ambient Intensity setting + (Light Color * Diffuse + Light Color * Specular) + Emission
Ambient:环境光
Diffuse:漫反射
Specular:镜面反射
Emission:自发光
Lighting On:灯光的总开关
SeparateSpecular On:高光总开关
纹理贴图:
1.纹理跟显示区域相等
2.纹理像素大于显示区域
Point: 就近采样
Bilinear:就近周围四个像素的平均【(上+中+下+左+右)/5】
Trilinear:就近周围8个像素的平均
3.纹理像素小于显示区域
锯齿 马赛克
Shader 1.0 纹理:
格式:
SetTexture [TextureName] {Texture Block}
TextureName:表示纹理变量
Previous:表示前面一个 SetTexture出来以后的像素
Primary:表示顶点计算出来的颜色
Texture:等于SetTexture当前的纹理变量
Constant:表示一个固定的颜色(1,1,1,1)
combine Primary * Texture:表示两个像素的乘法【越乘越暗,越加越亮】
combine src1 lerp (src2) src3:
Lerp:(差值)
让src1和src3进行混合
混合方式取决于src2的alpha值:
(1-t)A+tB
Shader "Custom/SetTexture"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_BlendTex ("Blend",2D) = "white"{}
_ConsColor ("Color",Color) = (1,0,0,1)
}
SubShader
{
Pass
{
Color(1,0,0,1)
SetTexture[_MainTex]
{
combine Primary * Texture
}
SetTexture[_BlendTex]
{
combine Previous + Texture
}
SetTexture[_BlendTex]
{
combine Previous lerp(Previous) Texture
}
SetTexture[_MainTex]
{
constantColor[_ConsColor]
combine Texture*Constant
}
}
}
}
设置constantColor的两种方式
1.constantColor(0,1,0,1)
constantColor(0,1,0,1)
SetTexture[_MainTex]
{
// constantColor(0,1,0,1)
combine Texture * Constant
}
2.Property
Conscolor("Color",Color)=(1,0,0,1)
SetTexture[_MainTex]
{
constantColor[_ConsColor]
combine Texture * Constant
}
Shader 1.0 适应所有的显卡
Shader 2.0 可以实现编程
相同点:渲染管线一样
#pragma vertex vertOne //定义一个顶点着色器的入口函数
#pragma fragment frag //定义一个片段着色器的入口函数Appdata从meshrender里面来的
POSITION:获取模型顶点的信息
NORMAL:获取法线信息
TEXCOORD(n):高精度的(float2,float3,float4) 从顶点传递信息到片段着色器
COLOR:表示低精度的 从顶点传递信息到片段着色器
TANGENT:获取切线信息
SV_POSITION:表示经过mvp矩阵,已经转化到屏幕坐标的位置
SV_Target //输出到哪个 render target
//v2f:顶点着色器的输出值,片段着色器的输入值
Image Effect Shader 解剖
Shader "Hidden/struct"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vertOne //定义一个顶点着色器的入口函数
#pragma fragment frag //定义一个片段着色器的入口函数
#include "UnityCG.cginc"
struct appdata // Appdata从meshrender里面来的
{
float4 vertex : POSITION; //POSITION:获取模型顶点的信息
float2 uv : TEXCOORD0;
};
//v2f:顶点着色器的输出值,片段着色器的输入值
struct v2f
{
//TEXCOORD0:高精度的(float2,float3,float4) 从顶点传递信息到片段着色器
float2 uv : TEXCOORD0;
//SV_POSITION:表示经过mvp矩阵,已经转化到屏幕坐标的位置
float4 vertex : SV_POSITION;
};
v2f vertOne (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target //输出到哪个 render target
{
fixed4 col = tex2D(_MainTex, i.uv);
// just invert the colors
col.rgb = 1 - col.rgb;
return col;
}
ENDCG
}
}
}
顶点着色器从fbx获取信息
struct appdata base{
float4 vertex:POSITION;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct appdata tan{
float4 vertex:POSITION;
float4 tangent:TANGENT;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct appdata full{
float4 vertex:POSITION;
float4 tangent:TANGENT;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD0;
float4 texcoord1:TEXCOORD1;
float4 texcoord2:TEXCOORD2;
float4 texcoord3:TEXCOORD3;
fixed4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
Shader2.0的矩阵变换
1.计算顶点的位置变换
2.计算顶点的颜色
Unity3D里面 矩阵是左乘:
1.将物体坐标系变换到世界坐标系
P(世界) = M(物体到世界的)*P(物体)
2.将世界坐标变换到相机坐标
P(相机) = M(世界到相机)*p(世界)