Unity3D-RayMarch-几何图元1-添加基本着色模型
效果图:

使用phong着色模型,将环境光、物体的漫反射光、镜面光三种光效加合而得到上图的效果
raymarch 的shader代码:
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "RayMarch/Primitives1_phong"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
Tags{ "RenderType" = "Opaque" }
LOD
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
#define PointLightPos fixed3(0, 3, 0)
#define LightColor float3(1,1,1)
#define GlobalAmibent float3(0.1,0.1,0.1)
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 BasicPhong(fixed3 lightDir, fixed3 normalDir, fixed3 viewDir, int matIndex) {
, Kd = , Ks = , Shininess = ;
float3 matColor = float3();
switch (matIndex) {
:
//极远处
matColor = float3(, , );
break;
:
matColor = float3(0.1, 0.1, 0.1);
break;
:
matColor = float3(); Shininess = ;
break;
:
matColor = float3(, 0.5, 0.5);
break;
:
matColor = float3(, 0.5);
break;
default:
break;
}
float3 amibent = Ka * GlobalAmibent * matColor;
float3 diffuse = Kd * LightColor * clamp(dot(normalDir, lightDir), , ) * matColor;
fixed3 reflectDir = reflect(-lightDir, normalDir);
float3 specular = Ks * LightColor * pow(clamp(dot(viewDir, reflectDir), , ), Shininess) * matColor;
float3 color = amibent + diffuse + specular;
return color;
}
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);
fixed3 lightPos = PointLightPos;
fixed3 lightDir = normalize(lightPos - pos);
float3 col = BasicPhong(lightDir, nor, rd, m);
return col;
}
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-几何图元1-添加基本着色模型的更多相关文章
- osg 基本几何图元
转自:osg 基本几何图元 //osg 基本几何图元 // ogs中所有加入场景中的数据都会加入到一个Group类对象中,几何图元作为一个对象由osg::Geode类来组织管理. // 绘制几何图元对 ...
- OpenCV入门系列教学(三)绘制几何形状及添加文本
一.绘制简单的几何形状和添加文本 opencv中绘制图形很简单,我们只需要使用下面这些常用函数即可. #画线 cv2.line() #画圆 cv2.circle() #画矩形 cv. rectangl ...
- Django编写RESTful API(五):添加超链接提高模型间的关联性
前言 在第四篇中,加入了用户模型,以及相关的认证和权限的功能.但是我们在使用的时候,会发现在访问http://127.0.0.1:8000/users/时看到的用户列表,不能够直接点击某个链接然后查看 ...
- ROS * 通过launch文件添加多个模型
我添加的是dae模型,urdf文件过两天贴 方法一 : <launch> <!-- these are the arguments you can pass this launch ...
- Unity3D NGUI 给button按钮添加单间事件
Unity3D中, NGUI 给button按钮添加单间事件的方法很多,在这里只给推荐一种比较常用的方法. 推荐方法:使用UIListener. 1.给button组价添加上UIListener.选择 ...
- Unity3D-RayMarch-几何图元-3添加阴影
效果图: 在RayMarch渲染算法中计算阴影非常简单,当射线碰撞到物体,从碰撞点逆着光源方向再次执行射线步进算法,如果这一过程中碰撞到了其他物体,则碰撞点被其他物体遮挡,该处具有阴影. shader ...
- Unity3D Animator控制参数和添加事件
Animator控制参数和添加事件 using UnityEngine; using System.Collections; public class AniControl : MonoBehavio ...
- openGl超级宝典学习笔记 (2) 7个主要的几何图元
点(GL_POINTS): 点总是正方形的像素,默认情况下,点的大小不受透视除法影响. 即无论与视点的距离怎样,它的大小都不改变.为了获得圆点.必须在抗锯齿模式下绘制点. 能够用glPointSize ...
- 【学习笔记】OSG 基本几何图元
例:geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); 来指定要利用这些数据生成一个怎么样的形状. ...
随机推荐
- {"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}
ElasticSearch-head 查询报 406错误码 {"error":"Content-Type header [application/x-www-form-u ...
- 配置samba的流程
1.关闭防火墙和selinuxservice iptables stopsetenforce 02.配置本地yummount /dev/cdrom /mediacd /etc/yum.repos.dc ...
- java 基础排序算法
冒泡: 从左往右依次比较相邻的两个数,将小数放在前面,大数放在后面. public void bobSort(){ for(int i=0;i<length-1;i++){//排序 ...
- Thinkphp5.0支付宝支付扩展库类库大全
Thinkphp5.0支付宝支付扩展库类库大全,包括手机网站支付.电脑网站支付.支付查询.退款.退款查询.对账单等. Thinkphp5.0支付宝调用方法: 电脑网站支付 Pagepay.php 调用 ...
- signalR客户端调用服务端方法失败
现象: 在VS中修改集线器代码后,重新生成解决方案,客户端js调用服务端方法提示undefined. 检查后台代码未发现错误. 检查js代码未发现错误(方法名称符合小驼峰规范). 解决方法: 先清理解 ...
- Channels实现扫码登录
参考了下别人说的原理,根据自己的逻辑实现,没有完全按照别人的原理来,所以不一定适用于大家,仅供参考吧!!! 流程如下: 1. web发起websocket链接,后端接受链接后立马发送第一次消息,为全局 ...
- js基本知识
1.js中的数据类型: js中的数据类型有undefined,boolean,number,string,object等5种,前4种为原始类型,第5种为引用类型. 2.typeof 返回的是字符串,有 ...
- thinkphp51 重定向 redirect()
thinkphp51 重定向 跨域 redirect() 可以重新定义新的路由,是fetch() 无法做到的.
- js验证对象类型
js验证对象类型 1. Object.prototype.toString.call() 这是最佳解决方案,可以用作通用方式处理.各种类型的判断依据类似于[object Object],替换的是后边的 ...
- Delphi全局热键的注册
1.在窗启动时创建ATOM;(aatom:ATOM;定义在private中) then begin aatom:=GlobalAddAtom('ZWXhotKey'); end; ) then beg ...