【Reading Notes】CP2-Surface Shaders and Texture Mapping

Unity Shader Graph 2D - 全息屏效果 在游戏中,有很多科技主题的场景会用到全息屏的效果,全息屏的效果能让游戏的科技感更强烈、更生动、更真实,同时增强玩家的沉浸感,带来不一样的交互体验。 阅读详情

Introduce

在这一章节,我们将探索Surface Sshader.将会从非常简单的材质开始,最后完成一个全息投影?和地形纹理融合(Blending)。还可以使用纹理动画,混合,以及其他任何我们想要的属性。本章知识点:
+ Diffuse shading 漫反射
+ Using packed arrays 使用数组
+ Adding texture to a shader 为shader添加纹理
+ Scrolling textures by modify uv values 纹理动画
+ Normal mapping 法相贴图
+ Creating a transparent material 创建透明材质
+ Creating a Holographic shader 创建全息的shader?
+ Packing and blending 纹理包装和混合
+ Creating a circle around you terrain

总的来说,在Surface Shader中有两步至关重要。第一,你必须指定材质的Physical(这个怎么翻译才好?)属性,例如:diffuse color(漫反射颜色)、smoothness(光滑系数)、transparency(通明度)。这些属性在unity的Surface function中被初始化,并被保存到surface output结构体中。第二步,这个surface out 将传递到lighting model中进行光照计算。这个特殊的函数将取得场景中的光照信息,结合surface output这些参数计算最后的片元的颜色。光照函数决定了当光照射到物体上的表现。下面是个流程图:
img

## Diffuse shading
在开始使用纹理映射之前,明白漫反射材质如何工作是很重要的。统一的颜色,光滑的表面但不足以反射光线(形成高光)。这样的材质最能表示Diffuse Shader了。在真实世界中纯漫反射的材质是不存在的;漫反射Shader在游戏中有着非常高的性能但同时伴随这比较差的美术表现。

一个漫反射Shader:

Shader "cookbook/PureDiffuse" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Lambert fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        //sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };
        fixed4 _Color;

        void surf (Input IN, inout SurfaceOutput o) {
            fixed4 c = _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

### Unity5 中的surfaceOutput sturct

SurfaceOutput
{
    fixed3 Albedo; //diffuse color 
    fixed3 Normal; //法线
    fixed3 Emiision; //自发光颜色
    fixed Alpha; //透明度
    half Specular; //高光强度
    fixed Gloss; //光泽度
}

SurfaceOuutputStandard
{
    fixed3 Albedo; //基本颜色(diffuse or specular)
    fixed3 Normal; //法线
    half3 Emission; //自发光颜色
    fixed Alpha; //透明度
    half Occlusion; //吸收??默认值是1
    half Smoothness; //光滑度,(0 = rough, 1 = smooth)
    half Metallic; //金属质感(0 = non-metal, 1 = metal)
}

SurfaceOutputStandardSpecular
{
    fixed3 Albedo; //基本颜色(diffuse color)
    fixed3 Normal; //法线
    half3 Emission;
    fixed Alpha;
    half Occlusion;
    half Smoothness;
    fixed3 Specular;// 高光颜色,和SurfaceOutput有着很大的不同,可以指定高光的颜色
}

是否可以正确的使用Surface Shader是一个关于能不能正确的初始化Surface output结构的问题。

Using Packed arrays

不是很负责的说,shader中的代码在屏幕上的每一个像素都至少执行一次。这是为什么GPU对于并行运算做了很大的优化。在CG的标准函数变量的设计也遵循这样的哲学(高并行)。明白这一点对于如何写出高性能的shader和优化shader至关重要。
在cg中有两类变量:sigle values & packed arrays(数组).可以简单的从类型的结尾判断,float3, int4,这样的packed array类型的总是以一个数字结尾。这样的类型有点像一个结构,包含了对应数目的sigle values 在cg中称作packed arrays,但又不是传统意义上的数组。。。它可以像一个普通的结构体一样通过域来访问他的成员,例如x、y、z、w;或者r、g、b、a。尽管对于x和r没有本质上的区别,但对于阅读上却意义巨大。对于shader的代码,总是在计算颜色和位置。略一段示例…..

### 说说矩阵 packed matrices

一个4x4的矩阵类型 float4x4 mat;

你可以这样访问矩阵的某一行某一列:float f = mat._m23

还可以这样:float4 vec = mat._m00_m11_22_33;

还有这样:float4 vec1 = mat[0] 等价于 mat._m00_m01_m02_m03

## 为Shader 添加材质

纹理可以让我们的shader很容易就达到比较真实的效果。为了更好和更有效率的使用纹理,我们需要理解2d的纹理是如何映射到3D模型上的,这个过程称作纹理映射(texture mapping)。都知道3D模型是由三角形构成,每一个顶点保存了可供Shader访问的数据。其中一个最重要的信息是UV Data(纹理坐标)。她由两个坐标组成分别是u & v 值的范围由0到1。她们表示2D图片中被映射到顶点的像素的xy坐标。uv坐标仅仅映射了顶点的颜色,但顶点内的颜色也需要进行映射计算,GPU通过最近的几个UV坐标的进行插值,然后根据插值后的uv从2D图片中读取对应的像素。来看看示例图:
img

UV Data 由3D模型编辑生成,一些模型丢失了UV Data 将不支持纹理映射。

Shader中进行纹理采样(tex2D函数):fixed3 c = tex2D(_MainTex, IN.uv_MainTex)

## 纹理动画

fixed xScrollValue = _ScrollXSpeed * _Time;
fixed yScrollValue = _ScrollYSpeed * _Time;

// Apply the final UV offset
scrolledUV += fixed2(xScrollValue, yScrollValue);

// Apply textures and tint
half4 c = tex2D (_MainTex, scrolledUV);
o.Albedo = c.rgb * _MainTint;
o.Alpha = c.a;

书中的例子简单的通多_Time去改变纹理坐标的偏移。这里自己写了个结合C#脚本,也是个十分简单的纹理动画,几个注意的地方在代码注释中说明。

//UVAni.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace _5xCookbook
{
    public class UVAni: MonoBehaviour
    {
        private Material m_mat;
        public int m_speed = 10;
        public int m_width = 1;
        public int m_height = 1;

        private float m_scaleX = 1;
        private float m_scaleY = 1;
        private float m_offsetX = 0;
        private float m_offsetY = 0;

        private float m_curOffsetX = 0;
        private float m_curOffsetY = 0;
        private int m_offsetStep = 0;
        void Start()
        {
            m_mat = GetComponent<Renderer>().material;
            m_speed = 10;
            ReCaculate();
        }

        public void ReCaculate()
        {
            m_offsetX = m_scaleX = 1.0f / m_width;
            m_offsetY = m_scaleY = 1.0f / m_height;
            m_offsetStep = 0;
            m_mat.SetTextureScale("_MainTex", new Vector2(m_scaleX, m_scaleY)); //设置纹理采样的范围,可以理解为缩放
            InvokeRepeating("SetTextureOffset", 0, 1.0f / m_speed);
        }

        private void SetTextureOffset()
        {
            int xStep = m_offsetStep % m_width;
            int yStep = m_height - 1 - m_offsetStep / m_width;
            m_curOffsetX = xStep * m_offsetX;
            m_curOffsetY = yStep * m_offsetY;
            string log = string.Format("ox: {0} oy: {1}", xStep, yStep);
            m_offsetStep++;
            m_offsetStep = m_offsetStep % (m_width * m_height);
            m_mat.SetTextureOffset("_MainTex", new Vector2(m_curOffsetX, m_curOffsetY));//采样纹理坐标偏移

            Debug.Log(log);
        }
    }
}

Shader:

Shader "CookbookShaders/Chapter02/UVAni"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata_base v)
            {
                v2f o;
                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); //可以在UnityCG.cginc中找到它的定义,Uniyt会把Inspectore中till和offset四个值保存在
                                                            //一个float4类型的变量中再Shader使用。这个函数算出最终的纹理坐标
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

法线映射

3D模型的每个三角面都有一个朝向,也就是这个三角面的法向量(向外的)。面的朝向对光照如何反射有这很大的影响。不同朝向的面,将朝不同方向反射光线,因此他们着色将显得不要一样。对于实际上非棱角分明的模型,这就显得很不自然。

为了规避这个问题,光照的反射将不去关注这个面的朝向,而是根据顶点的法向量(Normal Direction)。一种方式是为Shader添加一个法相贴图。法向量是除了纹理坐标之外最重要的数据,这是一个表示顶点方向的单位向量。一个顶点可能被多个三角面共享,所想顶点法向量是一个线性插值的结果。这样我们可以使低分辨率的模型看起来像高分辨率一样。

实现法相贴图

完整的Normal Mapping(法线映射)过程已经超出本章讨论范围,不过Unity为我们封装了一个函数:在UnityCG.cginc中定义了UnpackNormal()。这个函数将从法相贴图中解析并经过处理返回正确的顶点法向量,把纹理贴图内0-1范围的值转化到法向量的-1-1范围内。还可以通过缩放法向量的x,y来控制法相贴图的强度。

Shader "cookbook/Normal" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _NormalTex ("Normal Map", 2D) = "bump" {}
        _NormalItensity("Normal Itensity", Range(0,2)) = 1
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Lambert

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _NormalTex;

        struct Input {
            float2 uv_NormalTex;
        };

        fixed4 _Color;
        float _NormalItensity;

        void surf (Input IN, inout SurfaceOutput o) {
            float3 normalMap = UnpackNormal(tex2D (_NormalTex, IN.uv_NormalTex));
            normalMap.x *= _NormalItensity;
            normalMap.y *= _NormalItensity;
            normalMap = normalize(normalMap);
            // Albedo comes from a texture tinted by color
            fixed4 c = _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
            o.Normal = normalMap.rgb;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

创建透明材质

透明材质有几个关键的地方,总而言之,Surf shader中的Tags标签添加了一些描述Object如何进行渲染的信息。我们真正感兴趣的是Queue。Unity默认根据Object距离摄像机的距离进行排序,所以Object离摄像机越近就越晚被渲染。很多时候这很好,不过有时我们想要更多的控制场景中物体的渲染顺序。Unity提供了一些默认的值去确定物体的渲染队列,而不仅仅根据Object距离摄像机的距离。内置的值和说明如下:

img

对于Render queue value而言,越大就越晚被渲染。所以在渲染透明物体的时候,可以他Tags中的Queue设置为Transparent.

Shader "cookbook/Transparent" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags
        { 
            "RenderType" = "Transparent" 
            "Queue" = "Transparent"
            "IgnoreProjector" = "True"
        }
        LOD 200
        Cull Back

        CGPROGRAM

        #pragma surface surf Standard alpha:fade //alpha 混合

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };

        fixed4 _Color;

        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;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

创建全息效果(?Holographic)的Shader

Shader "cookbook/Silhouette" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _DotProduct("Rim effect", Range(-1, 1)) = 0.25
    }
    SubShader {
        Tags
        { 
            "RenderType" = "Transparent" 
            "Queue" = "Transparent"
            "IgnoreProjector" = "True"
        }
        LOD 200
        Cull Back

        CGPROGRAM

        #pragma surface surf Lambert alpha:fade nolighting //alpha 混合

        sampler2D _MainTex;
        float _DotProduct;
        fixed4 _Color;

        struct Input {
            float2 uv_MainTex;
            float3 worldNormal;
            float3 viewDir;
        };



        void surf (Input IN, inout SurfaceOutput o) {
            // Albedo comes from a texture tinted by color
            fixed4 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);
            o.Alpha = c.a * alpha;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

上面是Shader的最终代码,主要思想是计算定点法线与视线之间的夹角的点积,通过点积值计算一个Alpha的变化,越近Object中心法线与视线重合的时候Alpha=0边缘Alpha=1.

合并纹理&纹理混合(Packing and blending textures)

纹理不仅仅可以保存RGBA数据,随着我们的想法保存其他信息,如深度,前面的法线。还可以将纹理的RGBA通道分离成单独的R,G,B,A4个灰度图,在Shader中将这些通道组装起来,在有些时候可以起到减少总纹理大小的效果。
img

书中举了个地形纹理的例子,通过纹理混合得到最后的结果:关键点在于_BlendTex的使用,_BlendTex保存了RGBA各个通道的权重,组合成一个新的RGBA图片。权重的插值,通过cg的内置函数lerp(a, b, f)处理,如果需要对地形进行纹理混合的时候,通过一个权重的灰度图混合岩石,草地两份纹理就可以得到比较好的地形纹理效果,而且通过改变灰度图可以产生不同的效果,从而达到save size的效果。

Shader "CookbookShaders/Chapter02/TextureBlending" 
{
    Properties 
    {
        _MainTint ("Diffuse Tint", Color) = (1,1,1,1)

        //Add the properties below so we can input all of our textures
        _ColorA ("Terrain Color A", Color) = (1,1,1,1)
        _ColorB ("Terrain Color B", Color) = (1,1,1,1)
        _RTexture ("Red Channel Texture", 2D) = ""{}
        _GTexture ("Green Channel Texture", 2D) = ""{}
        _BTexture ("Blue Channel Texture", 2D) = ""{}
        _ATexture ("Alpha Channel Texture", 2D) = ""{}
        _BlendTex ("Blend Texture", 2D) = ""{}
    }

    SubShader 
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Lambert

        float4 _MainTint;
        float4 _ColorA;
        float4 _ColorB;
        sampler2D _RTexture;
        sampler2D _GTexture;
        sampler2D _BTexture;
        sampler2D _BlendTex;
        sampler2D _ATexture;

        struct Input 
        {
            float2 uv_RTexture;
            //float2 uv_GTexture;
            //float2 uv_BTexture;
            //float2 uv_ATexture;
            float2 uv_BlendTex;
        };

        void surf (Input IN, inout SurfaceOutput o) 
        {
            //Get the pixel data from the blend texture
            //we need a float 4 here because the texture 
            //will return R,G,B,and A or X,Y,Z, and W
            float4 blendData = tex2D(_BlendTex, IN.uv_BlendTex);

            //Get the data from the textures we want to blend
            float4 rTexData = tex2D(_RTexture, IN.uv_RTexture);
            float4 gTexData = tex2D(_GTexture, IN.uv_RTexture);
            float4 bTexData = tex2D(_BTexture, IN.uv_RTexture);
            float4 aTexData = tex2D(_ATexture, IN.uv_RTexture);

            //No we need to contruct a new RGBA value and add all 
            //the different blended texture back together
            float4 finalColor;
            finalColor = lerp(rTexData, gTexData, blendData.g);
            finalColor = lerp(finalColor, bTexData, blendData.b);
            finalColor = lerp(finalColor, aTexData, blendData.a);
            finalColor.a = 1.0;

            //Add on our terrain tinting colors
            float4 terrainLayers = lerp(_ColorA, _ColorB, blendData.r);
            finalColor *= terrainLayers;
            finalColor = saturate(finalColor);

            o.Albedo = finalColor.rgb * _MainTint.rgb;
            o.Alpha = finalColor.a;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}

画个圈圈

略

投影纹理映射(Projective Texture Mapping)详解 投影纹理映射(Projective Texture Mapping)目的是映射一张纹理到物体上,就像将幻灯片投影到墙上一样。该方法不需要在应用程序中指定顶点纹理坐标,实际上,投影纹理映射中使用的纹理坐标是在顶点着色程序中通过视点矩阵和投影矩阵计算得到的,通常也被称作投影纹理坐标(coordinates in projective space)。而我们常用的纹理坐标是在建模软件中通过手工调整纹理和3 阅读详情

相关推荐

unity 入门学习之(一)创建基本的3D游戏场景

1.准备工作,创建新工程2创建好的工程如下图中所示,在scene场景中包含一个主摄像机(main camera)和一个方向光(DirectionalLight),如下图右中所示,点击主摄像机在场景的右下角会出面预览窗口。3.创建基本的3D场景13.1 在现在的场景中增加一个平面,并在平面(plane)的insepector 视图中将transform组件的position属性值设置为(0,0,0),

dragon的专栏 2万+

【Three.js基础学习】29.Hologram Shader

three.js基础学习

weixin_41722662的博客 488

使用TextureMesh完成三维贴图(超全)

此博客建立在之前完成的项目上,之前的项目生成了TextureMesh所需要的输入option-0000.ply,mesh.ply。如果之前的项目没有做,参考链接:      https://blog.youkuaiyun.com/qq_42666483/article/details/80997718     (Bundler)     https://blog.youkuaiyun.com/qq_42666483/ar...

馒头Lynn的博客 1万+

投影纹理映射(Projective Texture Mapping)

摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文名“GPU编程与CG语言之阳春白雪下里巴人”    投影纹理映射(Projective Texture Mapping)最初由Segal在文章“Fast shadows and lighting effects using texture

liu_lin_xm的专栏 1万+

OpenGL学习笔记-2015.3.24——transform feedback缓存&粒子系统示例分析

transform feedback是OpenGL中比较酷炫的特性之一,他让客户端应用程序可以获取到渲染流水线上的顶点数据。基于这一特性实现了基于z-pass场景决策渲染技术,当然在此并没有去了解何为z-pass场景决策渲染技术,总之是一个可以有效减少渲染数据的输送。这里只是通过一个简单的例子系统,去了解transform feedback对象的使用方法。

所学、所思、所悟——coderling 8512

OpenGL 学习笔记-2015.4.18——立方体纹理映射-天空盒子-环境映射

立方体映射(cube-map)纹理是一种特殊类型的纹理,用于环境映射,使用一组图像并把他们作为立方体的面。立方体映射的6个面用正方形并且大小相同的6个子纹理表示。要从立方体纹理中采样的时候,使用的纹理坐标是3维,并且被看做来自原点的方向!方向指向用来读取纹理的立方体映射表面的位置。在这里例子中,有关于环境映射的代码,主要思想是通过观察向量和表面的法向量反射来确定采样的纹理坐标。     通过将一

所学、所思、所悟——coderling 6899

在Three.js中玩纹理投影

three.js加载纹理View demo 查看演示Download Source 下载源Texture projection is a way of mapping a texture onto a 3D object and making it look like it was projected from a single point. Think o...

culiao9310的博客 1188

统计学与R读书笔记(第四版)

统计学与R读书笔记(第四版) Statistics and R Reading Notes(统计学与R读书笔记(第四版)).rar

three.js自定义材质 切线空间及阴影

three.js自定义材质 切线空间及阴影

Zz10566的博客 1145

OpenGLES demo - 12. 材质贴图 Texture Mapping

OpenGLES 入门编程代码的第12课中讲解材质贴图的代码

HolographicShader.zip

https://www.byzhihuo.com/thread-43137-1-1.html shader全息扫描功能

MFC 数据类型转换(二)

MFC UNICODE字符串转化: 1、string转化为TCHAR* TCHAR* stringToTChar(string& strSour) { std::string m_csFileName = std::string(strSour);   TCHAR wc[MAX_PATH];   #ifdef UNICODE   _stprintf_s(wc, MAX_PAT

u011269801的专栏 731

projective_texture_mapping

投影矩阵的教程 Introduction Projective texture mapping is a method of texture mapping described by Segal [3] that allows the texture image to be projected onto the scene as if by a slide projector. Figure 1 shows some example screen shots from the projspot demo, available in the NVIDIA OpenGL SDK. Projective texture mapping is useful in a variety of lighting techniques, including shadow mapping [4]. This document provides some background and describes the steps involved in projective texture mapping in OpenGL. Projective texture mapping refers both to the way texture coordinates are assigned to vertices, and the way they are computed during rasterization of primitives. We usually think of texture mapping as “the application of a texture image to a primitive,” and while it certainly is that – there is more math going on than most folks think. If you have ever written your own rasterizer with support for mipmap filtered, perspective-correct, projective texture mapping, you no doubt became aware of the many subtle issues involved. We will begin by discussing the way that texture coordinates are computed during rasterization, and then we will discuss methods for assigning the texture coordinates to the vertices. We do not discuss filtering here, but there is a paper on Anisotropic Filtering at the NVIDIA developer web site that provides a good introduction to that topic. Figure 1.

Understanding the JVM Reading Notes 1

《深入理解Java虚拟机》读书笔记(1)第二章Java内存区域与内存溢出异常

我要成为大神!!! 340

统计学与R读书笔记(关于R软件的)

Statistics and R Reading Notes(统计学与R读书笔记(第四版)),看了就知道,非常好的书,很赞!

字节跳动程序媛教你如何刷算法题:面试手撕代码我就没怕过

本人上一次刷题还是大一的C语言期末考试……但是面试中算法考核截止上岸前一直保持着100%正确率的光辉记录。 本文将给你指明一条刷题的决胜指南。并从算法的重要性、题库的选择以及刷题的三大步骤分别进行讲解,彻底解决你所有关于面试算法所有的困扰。

Stay Hungry Stay Foolish 求知若饥 虚心若愚 2万+

sdk reading notes

1. Declaring Layout To measure its dimensions, a view takes into account its padding. Padding can be used to offset the content of the view by a specific amount of pixels Even though a view ca...

baobaoupup 156

【FPGA】Verilog代码实现温湿度传感器DHT11

#今天也是咸鱼的一天~ 因为参加Robei 杯 是要做一个机器人,先不说这个机器人具体怎么机器法,但是和外界互通的传感器肯定少不了,通过获取外界环境数据,进行处理,然后做出各种各样的功能。 先来讲个简单的模块,温湿度传感器DHT11。 DHT11介绍 DHT11是一款价格便宜,易于使用的温度湿度测量二合一传感器。它具有超小体积、极低功耗的特点。它使用单根总线与单片机进行双向的串行数据传输,信号传...

Ninquelote的博客 9162

Hologram Shader

全息图Shader效果图如下: 全息图是啥,自己百度下吧,(单一光照射。 传统的照片呈现的是真实的物理图像,而全息图则包含了被记录物体的尺寸、形状、亮度和对比度等信息。这些信息储存在一个很微小但却很复杂的干涉模式中。这个干涉模式是由激光产生的)Shader代码如下:Shader "Custom/MyHologram" { Properties {

a958832776的博客 2849

紫光PG2L100H平台DDR3 IP核调试实战:从AXI接口到状态机设计的避坑指南

本文详细介绍了在紫光PG2L100H FPGA平台上调试DDR3 IP核的实战经验,重点解析了AXI接口的特殊行为和状态机设计的关键技巧。通过具体代码示例和调试方法,帮助开发者规避常见陷阱,实现高性能DDR3控制器设计,达到1.2GB/s的稳定带宽。

weixin_28717969的博客 218

手把手教你学Simulink——基于电机驱动系统的场景实例:永磁同步电机(PMSM)在电动汽车中的矢量控制仿真

随着全球对环境保护的关注增加,电动汽车(Electric Vehicle, EV)因其环保特性而受到广泛关注。永磁同步电机(Permanent Magnet Synchronous Motor, PMSM)由于其高效率、高功率密度和良好的动态响应性能,在电动汽车驱动系统中得到了广泛应用。矢量控制(Field-Oriented Control, FOC)是实现PMSM高性能控制的关键技术之一,它能够实现对电机转矩和磁场的独立控制,从而达到类似直流电机的控制效果。本文将详细介绍如何使用来构建一个。

MHD0815的博客 1万+
上一篇: 【Reading Notes】CP1-Create a basic Standard Shader
下一篇: 【Reading Notes】CP3-Understanding Lighting Models
CoderLing
博客等级 码龄15年 40粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值