【学习日志】2022.08.30 List操作、RemoveAt、抽卡游戏、以Unity3D为介讲解计算机图形学(5000字敲得人麻了)Image Effect Shader 解剖 顶点灯光纹理贴图

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(世界)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基础的计算机图形学代码编程题及其答案,题目要求使用Unity3D实现一个简单的画线程序: 1. 创建一个新场景,添加一个空物体作为画布。 2. 编写脚本,实现以下功能: (1)定义一个公共变量lineColor,用于设置画线的颜色; (2)定义一个公共变量lineWidth,用于设置画线的粗细; (3)定义一个List<Vector3>类型的变量points,用于存储绘制线条所需要的点; (4)在Update函数中,如果鼠标左键按下,则将当前鼠标位置添加到points列表中; (5)在OnGUI函数中,创建一个GUI.Button,用于清除所有绘制的线条; (6)在OnRenderObject函数中,根据points列表中的点,绘制线条。 以下是代码实现: ```csharp using System.Collections; using System.Collections.Generic; using UnityEngine; public class DrawLine : MonoBehaviour { public Color lineColor = Color.black; // 画线颜色 public float lineWidth = 0.1f; // 画线粗细 private List<Vector3> points = new List<Vector3>(); // 存储绘制线条所需点 void Update() { if (Input.GetMouseButton(0)) { Vector3 mousePos = Input.mousePosition; mousePos.z = Camera.main.nearClipPlane; Vector3 worldPos = Camera.main.ScreenToWorldPoint(mousePos); points.Add(worldPos); } } void OnGUI() { if (GUI.Button(new Rect(10, 10, 100, 50), "Clear")) { points.Clear(); } } void OnRenderObject() { GL.PushMatrix(); GL.MultMatrix(transform.localToWorldMatrix); GL.Begin(GL.LINE_STRIP); GL.Color(lineColor); GL.LineWidth(lineWidth); for (int i = 0; i < points.Count; i++) { GL.Vertex(points[i]); } GL.End(); GL.PopMatrix(); } } ``` 请注意,此代码仅实现了基本的画线功能,并且没有考虑到性能和优化问题。如果需要更高效的绘图方案,请参考Unity的官方文档或其他资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值