目录

  • 前言
  • 我参考的资料
  • 坐标系与坐标变换
    • 世界坐标系
    • 模型坐标系
    • 眼坐标系
    • 裁剪坐标系
    • NDC坐标
    • 屏幕坐标系
    • MVP与坐标变换
    • 在shadermod中的世界坐标
  • GLSL入门
    • 面向像素
    • 顶点与片段着色器
    • 变量修饰
    • 向量操作
    • 矩阵运算
    • 使用纹理
    • 数学帮助函数
    • 内置变量
    • DRAWBUFFERS与颜色缓冲区
  • 光影包结构
  • 第一个着色器
    • composite.vsh
    • compsite.fsh
    • 简单滤镜特效
  • 坐标可视化
    • 深度缓冲纹理获取ndc坐标
    • ndc坐标可视化
    • 眼坐标可视化
    • “我的世界坐标” 可视化
  • 小结

前言

minecraft作为一款知名的沙盒游戏,影响了一代人 ,我从初中开始玩minecraft,一直玩到带学 。

minecraft本身的画质并不好,但是打了shadermod之后,可以达到炸裂般的高画质。shadermod又称光影mod,他需要配合光影包(即一系列的代码)来实现渲染的效果。渲染的效果取决于代码。

小时候,由于家里电脑配置并不好,无法流畅地运行光影mod,于是我开始想办法做“优化”,比如尝试删掉光影包里面的一些代码,或者减少其for循环的次数等等 。作为初中生,我无法理解其代码工作原理,当时很好奇,人生中第一次接触的编程语言就是GLSL。

变量,if,循环,在我眼里都很新奇,我尝试改变一个颜色变量的值,于是屏幕变成了对应的颜色,我发现虽然我不会写,但是我能够基于别人写的光影包,做出修改,我敲下第一段代码,来将太阳的颜色做出调整… 我发现自己对编程有点兴趣 这可能也为我之后选择计算机专业埋下了伏笔 。

基于别人的光影包来修改虽然很方便,但是我还是希望能自己动手编写一个属于自己的光影包。因为当时上初中不会编程 ,课业繁忙(其实就是自己太菜),一直没能实现这个愿望。到了带学,我逐渐忘记了这个愿望。直到我的hxd AbysStartdust 在他的Linux上搭建了一个mc服务器,我才重新玩回mc,想起来自己曾经有这么个愿望,正好下学期有图形学的课 遂学glsl。

我参考的资料

因为shadermod(光影mod)的参考资料非常少,学习起来非常困难,下面整理一些我经常看的资料:

  1. szszss大神的博客,强烈推荐 看他(她?)的博客,非常详细,教科书般的讲解,简直就是shadermod的中文手册+例程代码,对我的帮助非常大,感谢szszss大神!
  2. continue团队的教程,全英文生肉,无字幕,当时看的时候可费劲了。。。 这是他的油管空间 ,有热心hxd把它搬到b站上面来了,这是b站链接
  3. shadermod的wiki,全英文,不过比较简陋,只有一些变量最基本的介绍。。。
  4. wshxbqq的GitHub,是学习笔记,对GLSL有比较全面的介绍

其中对我帮助最大的要数老越共 szszss大神的博客,真的太强了!

坐标系与坐标变换

在GLSL中,或者说在opengl中,坐标系都是非常重要的东西。有了坐标系,就能够在扁平化的片段着色器中,确定像素的位置,这使得我们可以完成一些复杂的渲染,比如阴影。下面来介绍opengl中常用的坐标系

世界坐标系

世界坐标系即绝对坐标系,一个顶点在世界坐标系中的位置,不会随着视角或者相机的位置改变而改变。事实上,在任何情况下,一个顶点的世界坐标被确定,那么将永远不会发生变化。

模型坐标系

模型坐标系是当前顶点相对于模型而言的坐标系。模型发生旋转,模型坐标系轴随之转动。这个坐标系我们在编写着色器的时候不关心,因为总是要通过各种变换把它变换到其他坐标系。

眼坐标系

眼坐标系又名相机坐标系,视角坐标系。眼坐标系以摄像机视点中心为原点。和模型坐标系类似,顶点在眼坐标系中的坐标,随着相机(视角)的较度改变而改变。

值得注意的是,眼坐标系中的坐标是不包含投影变换的。比如下图中,红蓝方块位于眼坐标系x轴的相同位置

裁剪坐标系

裁剪坐标系通过投影而得到。投影的具体方法,就是根据摄像机的 镜头视场 ,将场景裁剪摄像机 能够看到 的部分,然后 投影 到摄像机 镜头


值得注意的是,投影变换只是获得场景中相机的可视部分,并未做透视除法只是裁剪掉了不可视的部分,因此名叫裁剪坐标系。

NDC坐标

NDC坐标又名归一化的设备坐标。裁剪坐标系下的坐标通过 透视除法 得到NDC坐标系下的坐标。

裁剪坐标通过 透视除法 得到NDC坐标。透视除法 其实就是裁剪坐标系下的坐标的xyz分量,除以自己的w分量。

透视除法,使得近处的坐标值大,远处的坐标值小。如图,红蓝方块具有不同的x轴坐标:

除此之外,NDC坐标的xyz都是[-1, 1]这个区间中的。

屏幕坐标系

屏幕坐标系中,屏幕左下角为(0, 0)而右上角为(1, 1)。

屏幕坐标由NDC坐标经过视口变换而得到,其实就是缩放(乘0.5再加0.5)

值得注意的是,因为由NDC坐标转换而来,屏幕坐标系同样包含了投影变换。比如如图的红蓝方块在屏幕坐标系中x轴位置就不相同

MVP与坐标变换

MVP变换又称:模型-视图-投影变换。在着色器中:

  1. 顶点的坐标一开始位于模型坐标系,通过模型(M -- Model)变换,变换到世界坐标系下
  2. 再通过视图(V -- View)变换,变换到眼坐标系下
  3. 然后通过投影(P -- Projection)变换,变换到裁剪坐标系
  4. 随后通过透视除法变换到NDC坐标系
  5. 最后做一个视口变换变换到屏幕坐标系

下面的流程图给出了顶点变换的全部流程:

#mermaid-svg-qehYcE08GLjs13xa .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-qehYcE08GLjs13xa .label text{fill:#333}#mermaid-svg-qehYcE08GLjs13xa .node rect,#mermaid-svg-qehYcE08GLjs13xa .node circle,#mermaid-svg-qehYcE08GLjs13xa .node ellipse,#mermaid-svg-qehYcE08GLjs13xa .node polygon,#mermaid-svg-qehYcE08GLjs13xa .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-qehYcE08GLjs13xa .node .label{text-align:center;fill:#333}#mermaid-svg-qehYcE08GLjs13xa .node.clickable{cursor:pointer}#mermaid-svg-qehYcE08GLjs13xa .arrowheadPath{fill:#333}#mermaid-svg-qehYcE08GLjs13xa .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-qehYcE08GLjs13xa .flowchart-link{stroke:#333;fill:none}#mermaid-svg-qehYcE08GLjs13xa .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-qehYcE08GLjs13xa .edgeLabel rect{opacity:0.9}#mermaid-svg-qehYcE08GLjs13xa .edgeLabel span{color:#333}#mermaid-svg-qehYcE08GLjs13xa .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-qehYcE08GLjs13xa .cluster text{fill:#333}#mermaid-svg-qehYcE08GLjs13xa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-qehYcE08GLjs13xa .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-qehYcE08GLjs13xa text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-qehYcE08GLjs13xa .actor-line{stroke:grey}#mermaid-svg-qehYcE08GLjs13xa .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-qehYcE08GLjs13xa .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-qehYcE08GLjs13xa #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-qehYcE08GLjs13xa .sequenceNumber{fill:#fff}#mermaid-svg-qehYcE08GLjs13xa #sequencenumber{fill:#333}#mermaid-svg-qehYcE08GLjs13xa #crosshead path{fill:#333;stroke:#333}#mermaid-svg-qehYcE08GLjs13xa .messageText{fill:#333;stroke:#333}#mermaid-svg-qehYcE08GLjs13xa .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-qehYcE08GLjs13xa .labelText,#mermaid-svg-qehYcE08GLjs13xa .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-qehYcE08GLjs13xa .loopText,#mermaid-svg-qehYcE08GLjs13xa .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-qehYcE08GLjs13xa .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-qehYcE08GLjs13xa .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-qehYcE08GLjs13xa .noteText,#mermaid-svg-qehYcE08GLjs13xa .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-qehYcE08GLjs13xa .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-qehYcE08GLjs13xa .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-qehYcE08GLjs13xa .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-qehYcE08GLjs13xa .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa .section{stroke:none;opacity:0.2}#mermaid-svg-qehYcE08GLjs13xa .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-qehYcE08GLjs13xa .section2{fill:#fff400}#mermaid-svg-qehYcE08GLjs13xa .section1,#mermaid-svg-qehYcE08GLjs13xa .section3{fill:#fff;opacity:0.2}#mermaid-svg-qehYcE08GLjs13xa .sectionTitle0{fill:#333}#mermaid-svg-qehYcE08GLjs13xa .sectionTitle1{fill:#333}#mermaid-svg-qehYcE08GLjs13xa .sectionTitle2{fill:#333}#mermaid-svg-qehYcE08GLjs13xa .sectionTitle3{fill:#333}#mermaid-svg-qehYcE08GLjs13xa .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-qehYcE08GLjs13xa .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa .grid path{stroke-width:0}#mermaid-svg-qehYcE08GLjs13xa .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-qehYcE08GLjs13xa .task{stroke-width:2}#mermaid-svg-qehYcE08GLjs13xa .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa .taskText:not([font-size]){font-size:11px}#mermaid-svg-qehYcE08GLjs13xa .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-qehYcE08GLjs13xa .task.clickable{cursor:pointer}#mermaid-svg-qehYcE08GLjs13xa .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-qehYcE08GLjs13xa .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-qehYcE08GLjs13xa .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-qehYcE08GLjs13xa .taskText0,#mermaid-svg-qehYcE08GLjs13xa .taskText1,#mermaid-svg-qehYcE08GLjs13xa .taskText2,#mermaid-svg-qehYcE08GLjs13xa .taskText3{fill:#fff}#mermaid-svg-qehYcE08GLjs13xa .task0,#mermaid-svg-qehYcE08GLjs13xa .task1,#mermaid-svg-qehYcE08GLjs13xa .task2,#mermaid-svg-qehYcE08GLjs13xa .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-qehYcE08GLjs13xa .taskTextOutside0,#mermaid-svg-qehYcE08GLjs13xa .taskTextOutside2{fill:#000}#mermaid-svg-qehYcE08GLjs13xa .taskTextOutside1,#mermaid-svg-qehYcE08GLjs13xa .taskTextOutside3{fill:#000}#mermaid-svg-qehYcE08GLjs13xa .active0,#mermaid-svg-qehYcE08GLjs13xa .active1,#mermaid-svg-qehYcE08GLjs13xa .active2,#mermaid-svg-qehYcE08GLjs13xa .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-qehYcE08GLjs13xa .activeText0,#mermaid-svg-qehYcE08GLjs13xa .activeText1,#mermaid-svg-qehYcE08GLjs13xa .activeText2,#mermaid-svg-qehYcE08GLjs13xa .activeText3{fill:#000 !important}#mermaid-svg-qehYcE08GLjs13xa .done0,#mermaid-svg-qehYcE08GLjs13xa .done1,#mermaid-svg-qehYcE08GLjs13xa .done2,#mermaid-svg-qehYcE08GLjs13xa .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-qehYcE08GLjs13xa .doneText0,#mermaid-svg-qehYcE08GLjs13xa .doneText1,#mermaid-svg-qehYcE08GLjs13xa .doneText2,#mermaid-svg-qehYcE08GLjs13xa .doneText3{fill:#000 !important}#mermaid-svg-qehYcE08GLjs13xa .crit0,#mermaid-svg-qehYcE08GLjs13xa .crit1,#mermaid-svg-qehYcE08GLjs13xa .crit2,#mermaid-svg-qehYcE08GLjs13xa .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-qehYcE08GLjs13xa .activeCrit0,#mermaid-svg-qehYcE08GLjs13xa .activeCrit1,#mermaid-svg-qehYcE08GLjs13xa .activeCrit2,#mermaid-svg-qehYcE08GLjs13xa .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-qehYcE08GLjs13xa .doneCrit0,#mermaid-svg-qehYcE08GLjs13xa .doneCrit1,#mermaid-svg-qehYcE08GLjs13xa .doneCrit2,#mermaid-svg-qehYcE08GLjs13xa .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-qehYcE08GLjs13xa .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-qehYcE08GLjs13xa .milestoneText{font-style:italic}#mermaid-svg-qehYcE08GLjs13xa .doneCritText0,#mermaid-svg-qehYcE08GLjs13xa .doneCritText1,#mermaid-svg-qehYcE08GLjs13xa .doneCritText2,#mermaid-svg-qehYcE08GLjs13xa .doneCritText3{fill:#000 !important}#mermaid-svg-qehYcE08GLjs13xa .activeCritText0,#mermaid-svg-qehYcE08GLjs13xa .activeCritText1,#mermaid-svg-qehYcE08GLjs13xa .activeCritText2,#mermaid-svg-qehYcE08GLjs13xa .activeCritText3{fill:#000 !important}#mermaid-svg-qehYcE08GLjs13xa .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-qehYcE08GLjs13xa g.classGroup text .title{font-weight:bolder}#mermaid-svg-qehYcE08GLjs13xa g.clickable{cursor:pointer}#mermaid-svg-qehYcE08GLjs13xa g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-qehYcE08GLjs13xa g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-qehYcE08GLjs13xa .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-qehYcE08GLjs13xa .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-qehYcE08GLjs13xa .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-qehYcE08GLjs13xa .dashed-line{stroke-dasharray:3}#mermaid-svg-qehYcE08GLjs13xa #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-qehYcE08GLjs13xa #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-qehYcE08GLjs13xa #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-qehYcE08GLjs13xa #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-qehYcE08GLjs13xa #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-qehYcE08GLjs13xa #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-qehYcE08GLjs13xa #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-qehYcE08GLjs13xa #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-qehYcE08GLjs13xa .commit-id,#mermaid-svg-qehYcE08GLjs13xa .commit-msg,#mermaid-svg-qehYcE08GLjs13xa .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-qehYcE08GLjs13xa g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-qehYcE08GLjs13xa g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-qehYcE08GLjs13xa g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-qehYcE08GLjs13xa g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-qehYcE08GLjs13xa .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-qehYcE08GLjs13xa .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-qehYcE08GLjs13xa .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-qehYcE08GLjs13xa .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-qehYcE08GLjs13xa .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-qehYcE08GLjs13xa .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-qehYcE08GLjs13xa .edgeLabel text{fill:#333}#mermaid-svg-qehYcE08GLjs13xa .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-qehYcE08GLjs13xa .node circle.state-start{fill:black;stroke:black}#mermaid-svg-qehYcE08GLjs13xa .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-qehYcE08GLjs13xa #statediagram-barbEnd{fill:#9370db}#mermaid-svg-qehYcE08GLjs13xa .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-qehYcE08GLjs13xa .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-qehYcE08GLjs13xa .statediagram-state .divider{stroke:#9370db}#mermaid-svg-qehYcE08GLjs13xa .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-qehYcE08GLjs13xa .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-qehYcE08GLjs13xa .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-qehYcE08GLjs13xa .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-qehYcE08GLjs13xa .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-qehYcE08GLjs13xa .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-qehYcE08GLjs13xa .note-edge{stroke-dasharray:5}#mermaid-svg-qehYcE08GLjs13xa .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-qehYcE08GLjs13xa .error-icon{fill:#522}#mermaid-svg-qehYcE08GLjs13xa .error-text{fill:#522;stroke:#522}#mermaid-svg-qehYcE08GLjs13xa .edge-thickness-normal{stroke-width:2px}#mermaid-svg-qehYcE08GLjs13xa .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-qehYcE08GLjs13xa .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-qehYcE08GLjs13xa .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-qehYcE08GLjs13xa .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-qehYcE08GLjs13xa .marker{fill:#333}#mermaid-svg-qehYcE08GLjs13xa .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-qehYcE08GLjs13xa {color: rgba(0, 0, 0, 0.75);font: ;}

模型变换
视图变换
投影变换
透视除法
视口变换
模型坐标系
世界坐标系
眼坐标系
裁剪坐标系
NDC坐标系
屏幕坐标系

在shadermod中的世界坐标

shadermod中的世界坐标和上文提到的世界坐标略有不同,我们称之为 “我的世界坐标” ,是以玩家为中心的坐标。

换句话说,相机位置即是 “我的世界坐标” 原点。

使用shadermod提供的视图模型变换矩阵,得到的世界坐标,其实是 “我的世界坐标” 。因为和常理不太相同,故单独提出来。

事实上,之所以转为 “我的世界坐标” 而不是定义上的世界坐标,是因为 “我的世界坐标” 对后续特性的编程实现提供便利。

GLSL入门

shadermod使用glsl语言编写,想要写shader,我们就必须先了解glsl。glsl类似c语言,常用的数据类型与流程控制,包括结构体,数组等,都有,其中增加mat(matrix矩阵)和vec(vector向量)类型,此外,还有sampler2D(采样器,即纹理)等类型,后面细

从0开始编写minecraft光影包(0)GLSL,坐标系,光影包结构介绍相关推荐

  1. 从零开始编写minecraft光影包(8)中级水面绘制 水下阴影与焦散

    完整资源: 我的Github地址 前情提要: 从0开始编写minecraft光影包(0)GLSL,坐标系,光影包结构介绍 从零开始编写minecraft光影包(1)基础阴影绘制 从零开始编写minec ...

  2. 从零开始编写minecraft光影包(6)天空绘制

    完整资源: 我的Github地址 前情提要: 从0开始编写minecraft光影包(0)GLSL,坐标系,光影包结构介绍 从零开始编写minecraft光影包(1)基础阴影绘制 从零开始编写minec ...

  3. 从零开始编写minecraft光影包(9)高级水面绘制 反射与屏幕空间反射

    完整资源: 我的Github地址 前情提要: 从0开始编写minecraft光影包(0)GLSL,坐标系,光影包结构介绍 从零开始编写minecraft光影包(1)基础阴影绘制 从零开始编写minec ...

  4. 从零开始编写minecraft光影包(5)简单光照系统,曝光调节,色调映射与饱和度

    完整资源: 我的Github地址 前情提要: 从0开始编写minecraft光影包(0)GLSL,坐标系,光影包结构介绍 从零开始编写minecraft光影包(1)基础阴影绘制 从零开始编写minec ...

  5. 从零开始编写minecraft光影包(4)泛光性能与品质优化

    完整资源: 我的Github地址 前情提要: 从0开始编写minecraft光影包(0)GLSL,坐标系,光影包结构介绍 从零开始编写minecraft光影包(1)基础阴影绘制 从零开始编写minec ...

  6. Java黑皮书课后题第3章:*3.1(代数:解一元二次方程)可以使用下面的公式求一元二次方程ax2+bx+c=0,编写程序提示用户输入a b c的值,并显示基于判断式的结果

    *3.1(代数:解一元二次方程)可以使用下面的公式求一元二次方程ax2+bx+c=0,编写程序提示用户输入a b c的值,并显示基于判断式的结果 题目 题目描述 运行示例 破题 代码 题目 题目描述 ...

  7. 定时器中断实验 编写程序使定时器0或者定时器1工作在方式2,自动重装载模式,定时500ms使两位数码管从00、01、02……98、99每间隔500ms加1显示。

    编写程序使定时器0或者定时器1工作在方式2,自动重装载模式,定时500ms使两位数码管从00.01.02--98.99每间隔500ms加1显示. 程序: #include <reg51.h> ...

  8. 定时器中断实验 编写程序使定时器0或者定时器1工作在方式1,定时500ms使两位数码管从00、01、02……98、99每间隔500ms加1显示。

    编写程序使定时器0或者定时器1工作在方式1,定时500ms使两位数码管从00.01.02--98.99每间隔500ms加1显示. 程序: #include <reg51.h> #defin ...

  9. 定时器中断实验 编写程序使定时器0或者定时器1工作在方式1,定时50ms触发蜂鸣器。

    编写程序使定时器0或者定时器1工作在方式1,定时50ms触发蜂鸣器. 程序: #include<reg51.h> sbit fm=P2^3; unsigned char cnt; int ...

  10. Spark 3.0 发布了,代码拉过来,打个包,跑起来!| 附源码编译

    作者 | 敏叔V587 责编 | 徐威龙 封图| CSDN 下载于视觉中国 Spark3.0已经发布有一阵子了,官方发布了预览版,带来了一大波更新,对于我们程序员来说,首先当然是代码拉过来,打个包,跑 ...

最新文章

  1. 微服务该如何设计缓存?
  2. Bytom BIP-32协议和BIP-44协议解读
  3. python定义词典_python – 自定义类是一个字典,但初始化没有字典副本?
  4. MTK Read/Write IMEI from App
  5. Nginx--虚拟主机
  6. 在C代码调用C++代码
  7. 2.2 PostgreSQL 概念
  8. vector元素的读取
  9. 11 款最好 CSS 框架 让你的网站独领风骚
  10. 5.PSR-7: HTTP message interfaces
  11. php类似indexof的方法[转]
  12. ET游戏框架之环境搭建与运行
  13. 关于VB中Print函数在数组中换行的理解
  14. ldaptemplate 分页_分页机皮带跑偏调整方法
  15. pythonppt_Python简介ppt
  16. 手游联运系统后台有什么功能?后台功能大全!
  17. android 发送短信例子
  18. Windows/Linux日志分析
  19. MySQL技术总结第一篇
  20. 网络相关基础知识总结(一)吞吐量测试吞吐量与带宽区别

热门文章

  1. 天涯海客邮件搜索群发大师 使用说明
  2. stc12c5a单片机c语言adc,STC12C5A60S2单片机的ADC采样程序分享
  3. 汽车的主要结构参数和性能参数
  4. 二十三、小程序中的三级下拉框(下拉菜单)
  5. 计算机网络nic,NIC,什么是NIC,NIC介绍--电子百科词库--科通芯城,IC及其他电子元器件交易型电商平台100%正品保证...
  6. 1211: 【入门】数字走向IV
  7. mysql sql 隐藏信息
  8. VMWare虚拟机启动img文件
  9. 世间谤我、欺我、辱我、笑我,为之奈何?
  10. Docker mysql [Warning] World-writable config file ‘.cnf‘ is is ignored