效果图:

将下面的shader代码对应的Material拖给一个面片,即可看到效果。

shader代码:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "RayMarch/Primitives0_diffuse"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

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

            sampler2D _MainTex;
            float4 _MainTex_ST;

            //###################################################################################
            //sdf:define primitives
            float sdPlane(float3 p,float planeYPos)
            {
                return p.y - planeYPos;
            }

            float sdSphere(float3 p, float3 spherePos, float radius)
            {
                return length(p - spherePos) - radius;
            }
            //###################################################################################

            //###################################################################################
            //primitives boolean operation
            //求并集
            float2 opU(float2 d1, float2 d2)
            {
                return (d1.x<d2.x) ? d1 : d2;
            }
            //###################################################################################

            // define the scene
            float2 map(in float3 pos)
            {
                //plane
                //float2(x,y)的第二个参数定义了该物体的材质id,在render环节,可以根据id做不同处理
                float2 plane = float2(sdPlane(pos, -);
                float2 ball_1 = float2(sdSphere(pos, float3(, , ), );
                float2 ball_2 = float2(sdSphere(pos, float3(, , ), );
                float2 ball_3 = float2(sdSphere(pos, float3(-, , ), );
                //求物体的并集
                float2 res = opU(opU(opU(ball_1, ball_2), ball_3),plane);
                return res;
            }

            float2 castRay(in float3 ro, in float3 rd)
            {
                float tmin = 1.0;
                //射线最大允许经过的距离
                float tmax = 100.0;
                //当前已经过的距离
                float t = tmin;
                //材质id
                float m = -1.0;
                //最大迭代次数定位64
                ; i<; i++)
                {
                    //距离精度随距离的增加而减小
                    float precis = 0.0005*t;
                    //获得场景中物体距离该点的距离,及距离最近物体的材质id
                    float2 res = map(ro + rd*t);
                    //如果与场景物体发生碰撞,或者射线行进距离超出最大范围,则跳出迭代
                    if (res.x<precis || t>tmax) break;
                    t += res.x;
                    m = res.y;
                }
                if (t>tmax) m = -1.0;
                return float2(t, m);
            }

            //计算碰撞点处物体表面的法线
            float3 calcNormal(in float3 pos)
            {
                float3 eps = float3(0.0005, 0.0, 0.0);
                float3 nor = float3(
                    map(pos + eps.xyy).x - map(pos - eps.xyy).x,
                    map(pos + eps.yxy).x - map(pos - eps.yxy).x,
                    map(pos + eps.yyx).x - map(pos - eps.yyx).x);
                return normalize(nor);
            }

            float3 render(in float3 ro, in float3 rd)
            {
                //投掷射线,获得与所场景物体的碰撞信息
                float2 res = castRay(ro, rd);
                float t = res.x;
                float m = res.y;
                float3 pos = ro + t*rd;
                float3 nor = calcNormal(pos);
                float3 ref = reflect(rd, nor);
                //漫反射着色
                fixed3 lightPos = fixed3(, , );
                fixed3 lightDir = normalize(lightPos - pos);
                , );
                float3 col = float3(dif, dif, dif);
                return float3(clamp(col, 0.0, 1.0));

            }

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //虚拟摄像机坐标
                float3 ro = float3(,,-);
                //投影面某点坐标
                float3 p = float3(i.uv - float2();
                //投掷射线
                float3 rd = normalize(p - ro);
                fixed4 col = fixed4(render(ro, rd).rgb, );
                // gamma校正
                col.rgb = pow(col.rgb, float3(0.4545, 0.4545, 0.4545));
                return col;
            }
            ENDCG
        }
    }
}

Unity3D-RayMarch-几何图元0的更多相关文章

  1. osg 基本几何图元

    转自:osg 基本几何图元 //osg 基本几何图元 // ogs中所有加入场景中的数据都会加入到一个Group类对象中,几何图元作为一个对象由osg::Geode类来组织管理. // 绘制几何图元对 ...

  2. 【学习笔记】OSG 基本几何图元

    例:geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); 来指定要利用这些数据生成一个怎么样的形状. ...

  3. openGl超级宝典学习笔记 (2) 7个主要的几何图元

    点(GL_POINTS): 点总是正方形的像素,默认情况下,点的大小不受透视除法影响. 即无论与视点的距离怎样,它的大小都不改变.为了获得圆点.必须在抗锯齿模式下绘制点. 能够用glPointSize ...

  4. Android5.0新特性——图片和颜色(drawable)

    图片和颜色 tint属性 tint属性一个颜色值,可以对图片做颜色渲染,我们可以给view的背景设置tint色值,给ImageView的图片设置tint色值,也可以给任意Drawable或者NineP ...

  5. vc++ 6.0下Glut的配置 及 Glut 框架介绍

    2014-04-08  16:18:30 一.配置Glut 学习来源: http://blog.sina.com.cn/s/blog_5f0cf7bd0100c9oa.html 亲测可行. Glut的 ...

  6. (转载)Cocos2dx-OpenGL ES2.0教程:使用VBO索引(4)

    在上一篇文章中,我们介绍了uniform和模型-视图-投影变换,相信大家对于OpenGL ES 2.0应该有一点感觉了.在这篇文章中,我们不再画三角形了,改为画四边形.下篇教程,我们就可以画立方体了, ...

  7. Android 5.0 新特性

    Material Design Material Design简介 Material Design是谷歌新的设计语言,谷歌希望寄由此来统一各种平台上的用户体验,Material Design的特点是干 ...

  8. OpenGL ES2.0基础入门

    1.OpenGL ES 1.x渲染管线(又称为渲染流水线) (1).基本处理: 基本处理主要是设定3D空间中物体的顶点坐标.顶点对应的颜色.顶点的纹理坐标等属性,并且指定绘制方式. 常见的绘制方式有: ...

  9. OpenGL ES 2.0 纹理映射

    纹理坐标用符点数表示,范围一般从0.0到1.0,在纹理坐标系中.纹理坐标系原点在左上侧,向右为S轴,向下为T轴.两个轴的取值范围都是0.0-1.0. 纹理映射 纹理映射:把一幅纹理图应用到相应的几何图 ...

随机推荐

  1. intellij idea工具 DeBug调试

    断点的设定和eclipse一样,只要点一下就可以,下面是我设定的几个断点,再下面的三个窗口是用来调试代码的,这个和eclipse类似 调试常用的快捷键 F9 resume programe 恢复程序 ...

  2. python 内建函数__new__的单例模式

    今天好奇__init__和__new__的区别是什么? 我了解到: __init__:只是单纯的返回一个类对象的实例,是在__new__之后调用的 __new__:创建一个类对象实例, class S ...

  3. RNN探索(2)之手写数字识别

    这篇博文不介绍基础的RNN理论知识,只是初步探索如何使用Tensorflow,之后会用笔推导RNN的公式和理论,现在时间紧迫所以先使用为主~~ import numpy as np import te ...

  4. Mysql 5 忘记root密码,设置免密登陆

    1.修改my.cnf配置文件 vi /etc/my.cnf #允许免密认证登陆 skip-grant-tables = true 2.重启Mysql数据库并登陆数据库修改root用户密码 system ...

  5. AES/CBC/PKCS7Padding加密方式

    在网上找了大半天资料,终于找到一个可以用的 public static class AES { // 算法名称 final static String KEY_ALGORITHM = "AE ...

  6. 由2个鸡蛋从100层楼下落到HashMap的算法优化联想

    题目: 有一栋楼共100层,一个鸡蛋从第N层及以上的楼层下落会摔破,在第N层以下的楼层不会摔破,给你两个鸡蛋,设计方案找出N,并且保证在最坏的情况下,最小化鸡蛋下落的次数.(鸡蛋没有摔破是可以重复利用 ...

  7. 14Linux_BIND-Linux就该这么学

    bind 域名解析 域名→ip地址:正向解析 ip地址→域名:反向解析 主服务器:做管理 从服务器:同步 缓存服务器:转发

  8. EasyUI 1.3.2 中 Combobox自动检索 键盘上下选择Bug问题

    EasyUI 自带的Combobox控件,提供了下拉列值自动检索功能. 在用到的EasyUI 1.3.2版本中还是有点问题,在键盘上下键移动选择过程中只能定位在第一个,不能正常向下移动 问题解决方式: ...

  9. docker原理(转)

    可能是把Docker的概念讲的最清楚的一篇文章 [编者的话]本文只是对Docker的概念做了较为详细的介绍,并不涉及一些像Docker环境的安装以及Docker的一些常见操作和命令. Docker是世 ...

  10. ES6 Promise 用法转载

    Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方法,原型上有then.catch等同样很眼熟的方法. 那就new一个 var p = new Promise( ...