zoukankan      html  css  js  c++  java
  • 关于UnityShader的入门学习 (一)

    前言

      关于UnityShader方面的知识有很多,但真正能让读者读懂并很快上手操作的少之又少,在这里我简单介绍下关于Shader的一些入门知识,如有出入请大佬们多多指点!

    图形学的基础知识

      1.Unity游戏物体上需挂载Mesh Filter组件,Mesh Filter中存储一个Mesh网格(用于存储形成图形的所有三角面的顶点信息)。

      2.Unity游戏物体上需挂载Mesh Renderer组件,Mesh Renderer为渲染组件,通俗来讲就是按照Mesh网格上的顶点信息将图形显示出来,赋予皮肤、颜色等等。

      3.Mesh Renderer中Material(材质)及我们编写的Shader所依赖的,用于实现效果的依托。

    Shader、OpenGL、DirectX之间的关系

      通俗来讲,Shader是一种渲染命令,由OpenGL或者DirectX进行解析进而渲染出丰富多彩的图形。

      其中OpenGL一般用于移动平台,DirectX一般用于PC平台。

      

    Shader的语言分类

      1.GLSL OpenGL语言

      2.HLSL DirectX语言

      3.CG  夸平台语言

      4.ShaderLab Unity中对上述语言的通用封装

    关于Shader中的属性代码

    Shader"Mocha/01 myshader"{//这里制定Shader的名字,不要求与文件名保持一致
    
        Properties{
        //属性
        _Color("Color",Color)=(1,1,1,1)        //颜色float4
        _Vector("Vector",Vector)=(1,2,3,4)    //向量float4
        _Int("Int",Int)=1234                //整数float
        _Float("Float",Float)=4.5            //小数float
        _Range("Range",Range(1,11))=6        //随机数float
        _2D("Texture",2D)="white"{}            //图片sampler2D(其中white代表当未指定图片时默认其未一张白色的图片,也可改为其他颜色)
        _Cube("Cube",Cube)="White"{}        //立方体纹理samplerCube(其中white代表当未指定图片时默认其未一张白色的图片,也可改为其他颜色)用于天空盒子等
        _3D("Texure",3D) = "White"{}        //3D贴图sampler3D(其中white代表当未指定图片时默认其未一张白色的图片,也可改为其他颜色)
        }
    
        //SubShader可以有很多个,显卡运行效果的时候,从第一个SubShader开始,如果里面的效果全部可以实现,那么就使用第一个SubShader,如果不支持则进行下一个
        SubShader{
            
            //每个SubShader至少有一个Pass块  相当于一个方法
            Pass{
            
            //在这里编写Shader代码
                CGPROGRAM
                //使用CG语言编写Shader代码
                //每次使用上面定义好的属性时需要重新定义一下并且此处每行代码“;”结束
                //取到的值为上述默认定义好的值
                float4 _Color;
                float4 _Vector;
                float _Int;
                float _Float;
                float _Range;
                sampler2D _2D;
                samplerCube _Cube;
                sampler3D _3D;
    
                //float half fixed 的区别
                //一般小数这三个都可以声明定义
                float t1;
                half t2;
                fixed t3;
                half2 t4;
                fixed2 t5;
                //区别在于范围不同 
                //float 32位
                //half 16位  -6万 -- +6万
                //fixed 11位  -2 -- +2 (一般颜色用fixed)
    
                ENDCG
    
            }
    
        }
    
        //当所有的SubShader都不符合的时候,则用此备胎Shader效果可自定义备胎Shader
        Fallback "VertexLit"
    }

     关于Shader中的常用语义

      1.从应用程序传递到顶点函数的语义有哪些a2v
        POSITION 顶点坐标(模型空间下的)
        NORMAL 法线( 模型空间下)
        TANGENT 切线(模型空间)
        TEXCOORD0 ~n 纹理坐标
        COLOR 顶点颜色

      2.从顶点函数传递给片元函数的时候可以使用的语义
        SV_POSITION 剪裁空间中的顶点坐标(一般是系统直接使用)
        COLOR0 可以传递一组值 4个
        COLOR1 可以传递一组值 4个
        TEXCOORD0~7 传递纹理坐标

      3.片元函数传递给系统
        SV_Target 颜色值,显示到屏幕上的颜色

    Shader "Mocha/02 secondshader can run"{
    
        SubShader{
        
            Pass{
                CGPROGRAM
                //顶点函数 这里只是声明了顶点函数的函数名
                //基本作用 完成顶点坐标从模型空间到剪裁空间的转换(从游戏环境到相机视野屏幕上)
    #pragma vertex vert
                //片元函数 这里只是声明了片元函数的函数名
                //基本作用 返回模型对应的屏幕上的每一个像素的颜色值
    #pragma fragment frag
                
                float4 vert(float4 v : POSITION) : SV_POSITION{//通过语义来告诉系统我这个参数是干嘛的
                //比如POSITION是告诉系统我需要顶点坐标
                //比如SV_POSITION用来解释说明返回值,返回值是剪裁空间下的顶点坐标
    
                //转换剪裁空间坐标的算法,也可直接调用包装好的方法
                float4 pos=mul(UNITY_MATRIX_MVP,v);
                return pos;
                
                }
                fixed4 frag() : SV_Target{
                return fixed4(0.5,0.5,1,1);
                }
    
    
                ENDCG
            }
        
        }
        Fallback "VertexLit"
    
    }

    使用结构体进行存储传递数据

    Shader "Mocha/03 Use Struct"{
    
        SubShader{
        
            Pass{
                CGPROGRAM
                //顶点函数 这里只是声明了顶点函数的函数名
                //基本作用 完成顶点坐标从模型空间到剪裁空间的转换(从游戏环境到相机视野屏幕上)
    #pragma vertex vert
                //片元函数 这里只是声明了片元函数的函数名
                //基本作用 返回模型对应的屏幕上的每一个像素的颜色值
    #pragma fragment frag
                
                //使用结构体存储
                //a2v 即 application to vertex
                struct a2v{ 
                    float4 vertex:POSITION;//告诉Unity把模型空间下的顶点坐标填充给vertex
                    float3 normal:NORMAL;//告诉Unity把模型空间下的法线方向填充给normal
                    float4 texcoord:TEXCOORD0;//告诉Unity把第一套纹理坐标填充给texcoord
                };
    
                //使用结构体存储
                struct v2f{
                    float4 position:SV_POSITION;//告诉Unity存储剪裁空间下的顶点坐标
                    float3 temp:COLOR0;//临时测试顶点到片元函数之间的数据传递,此处将顶点中的法线作为颜色传递给片元函数显示
                };
    
                v2f vert(a2v v){
                    v2f f;
                    f.position=mul(UNITY_MATRIX_MVP,v.vertex); 
                    f.temp=v.normal;
                    return f;
                }
                fixed4 frag(v2f f) : SV_Target{
                return fixed4(f.temp,1);
                }
    
    
                ENDCG
            }
        
        }
        Fallback "VertexLit"
    
    }
  • 相关阅读:
    一步一步实现一个简单的OS(简单的让boot载入setup)
    hdu 1203 I NEED A OFFER!(01背包)
    面向服务与微服务架构
    ThreadLocal,LinkedBlockingQueue,线程池 获取数据库连接2改进
    deeplearning.net 0.1 document
    怎样有效的降低反复的代码
    redmine 自己定义字段mysql表结构
    c语言中使用宏,需要注意的的几点
    gcc自有的define语法,解决变量多次自加的问题
    ubuntu16.04 安装docker
  • 原文地址:https://www.cnblogs.com/mrmocha/p/7967015.html
Copyright © 2011-2022 走看看