明天得开始研究别人是怎么处理材质的了。目前使用的方法是
(反射来源×反射基准)×折射比率+(光源×材质颜色)×(1-折射比率)+[(折射来源+底面反射)×衰减+(1-衰减)]×透明物体内部颜色。
等材质完全做完之后,目前的渲染算法就可以为GI服务了。
最后是计算混合的代码:
1 VBool VL_RayRenderer::GetSample(IVL_RayGeometry::UnmanagedList& Objects , VRayPoint Position , VRayVector Direction , IVL_RayGeometry*& Geometry , VL_RayObjectSample& Sample)
2 {
3 VBool Available=false;
4 for(VInt i=0;i<Objects.GetCount();i++)
5 {
6 VL_RayObjectSample TempSample;
7 if(Objects[i]->GetNearestSample(Position,Direction,true,TempSample))
8 {
9 if(!Available)
10 {
11 Geometry=Objects[i];
12 Sample=TempSample;
13 Available=true;
14 }
15 else if(TempSample.DirectionScale<=Sample.DirectionScale)
16 {
17 Geometry=Objects[i];
18 Sample=TempSample;
19 }
20 }
21 }
22 return Available;
23 }
24
25 VRayColor VL_RayRenderer::GetRefractionColor(IVL_RayGeometry::UnmanagedList& Objects , IVL_RayGeometry* Object , VRayPoint Position , VRayVector Direction , VInt ReflectionCounter)
26 {
27 VL_RayObjectSample Sample;
28 if(Object->GetNearestSample(Position,Direction,false,Sample))
29 {
30 VDouble RefractionLength=(Sample.Position-Position).Length();
31 VDouble InternalRatio=1-pow(Sample.RefractionIndex,-RefractionLength);
32 VDouble OutRatio=0;
33 VRayColor OutColor(0,0,0);
34 VRayColor ReflectionColor(0,0,0);
35 /*折射*/
36 {
37 VDouble SinB,CosB;
38 VRayVector OutDirection=(-Sample.Normal).Refract(Sample.RefractionSinRatio,Direction,SinB,CosB);
39 OutRatio=pow(CosB,Sample.RefractionRefindex);
40 if(OutRatio>=Zero)
41 {
42 VRayVector OutPosition=Sample.Position+OutDirection.Normalize().Scale(ReflectionOffsetScale);
43 OutColor=GetSampleColor(Objects,OutPosition,OutDirection,ReflectionCounter);
44 }
45 }
46 /*反射*/
47 {
48 VBool ReflectionEnabled=Sample.ReflectionEnabled && ReflectionCounter>0 && !(1-OutRatio>=Zero);
49 if(ReflectionEnabled)
50 {
51 VRayVector ReflectionDirection=Sample.Normal.Reflect(Direction);
52 VRayVector ReflectionPosition=Sample.Position+ReflectionDirection.Normalize().Scale(ReflectionOffsetScale);
53 ReflectionColor=GetRefractionColor(Objects,Object,ReflectionPosition,ReflectionDirection,ReflectionCounter-1);
54 }
55 }
56 /*混合*/
57 OutColor=(OutColor.Scale(1-Sample.RefractionFaceRatio)+Sample.Color.Scale(Sample.RefractionFaceRatio));
58 VRayColor MixColor=OutColor.Scale(OutRatio)+ReflectionColor.Scale(1-OutRatio);
59 /*衰减*/
60 return Sample.RefractionInternal.Scale(InternalRatio)+(MixColor*Sample.RefractionInternal).Scale(1-InternalRatio);
61 }
62 else
63 {
64 return VRayColor(0,0,0);
65 }
66 }
67
68 VRayColor VL_RayRenderer::GetSampleColor(IVL_RayGeometry::UnmanagedList& Objects , VRayPoint Position , VRayVector Direction , VInt ReflectionCounter)
69 {
70 IVL_RayGeometry* Geometry=0;
71 VL_RayObjectSample Sample;
72 if(GetSample(Objects,Position,Direction,Geometry,Sample))
73 {
74 VRayColor Light(0,0,0);
75 VRayColor Reflection(0,0,0);
76 VRayColor Refraction(0,0,0);
77 /*光源*/
78 for(VInt i=0;i<Lights.GetCount();i++)
79 {
80 VRayColor LightColor=Lights[i]->GetLight(Sample.Position);
81 VRayVector LightDirection=Lights[i]->GetDirection(Sample.Position).Normalize();
82 if(LightDirection.Length()<Zero)
83 {
84 Light+=LightColor;
85 }
86 else
87 {
88 VBool Skip=false;
89 VL_RayObjectSample LookBackSample;
90 if(GetSample(Objects,Sample.Position-LightDirection.Normalize().Scale(ReflectionOffsetScale),-LightDirection,Geometry,LookBackSample))
91 {
92 VRayColor LookBackColor=Lights[i]->GetLight(LookBackSample.Position);
93 if(LookBackColor.R+LookBackColor.G+LookBackColor.B>Zero)
94 {
95 Skip=true;
96 }
97 }
98 if(!Skip)
99 {
100 VDouble Scale=Sample.Normal.Normalize()*(-LightDirection);
101 if(Scale>0)
102 {
103 Light+=LightColor.Scale(Scale);
104 }
105 }
106 }
107 }
108 /*反射*/
109 if(ReflectionCounter>0 && Sample.ReflectionEnabled)
110 {
111 VRayVector ReflectedDirection=Sample.Normal.Reflect(Direction.Scale(-Sample.DirectionScale));
112 VRayVector ReflectedPosition=Sample.Position+ReflectedDirection.Normalize().Scale(ReflectionOffsetScale);
113 Reflection=GetSampleColor(Objects,ReflectedPosition,ReflectedDirection,ReflectionCounter-1);
114 }
115 /*折射*/
116 if(Sample.RefractionEnabled)
117 {
118 VRayVector RefractionDirection=Sample.Normal.Refract(1/Sample.RefractionSinRatio,Direction);
119 if(RefractionDirection.Length()>Zero)
120 {
121 VRayPoint RefractionPosition=Sample.Position+RefractionDirection.Normalize().Scale(ReflectionOffsetScale);
122 Refraction=GetRefractionColor(Objects,Geometry,RefractionPosition,RefractionDirection,ReflectionCounter);
123 Refraction=Sample.Color.Scale(Sample.RefractionFaceRatio)+Refraction.Scale(1-Sample.RefractionFaceRatio);
124 }
125 }
126 /*混合*/
127 return
128 (Light*Sample.Color).Scale(1-Sample.ReflectionRatio)+
129 (Reflection*Sample.ReflectionBase).Scale(Sample.ReflectionRatio)+
130 Refraction;
131 }
132 else
133 {
134 return VRayColor(0,0,0);
135 }
136 }
137
138 void VL_RayRenderer::Render(IVL_RayGeometry::UnmanagedList& Objects , IVL_RayRenderingInformation* Information)
139 {
140 VL_WinBitmap::Ptr Buffer=new VL_WinBitmap(Information->GetBufferWidth(),Information->GetBufferHeight(),VL_WinBitmap::vbb24Bits,true);
141 VInt BufferWidth=Buffer->GetWidth();
142 VInt BufferHeight=Buffer->GetHeight();
143 for(VInt Y=0;Y<BufferHeight;Y++)
144 {
145 VByte* ScanLine=Buffer->GetScanLines()[Y];
146 for(VInt X=0;X<BufferWidth;X++)
147 {
148 VByte* Pixel=&ScanLine[X*3];
149 VDouble XRatio=(VDouble)(X*2-BufferWidth)/BufferWidth;
150 VDouble YRatio=(VDouble)(Y*2-BufferHeight)/BufferHeight;
151 VRayVector RenderingDirection=(FScreenCenter-FPosition)+FScreenRightVector.Scale(XRatio)+FScreenDownVector.Scale(YRatio);
152 VRayColor RenderingColor=GetSampleColor(Objects,FPosition,RenderingDirection,MaxReflectionLevelCount);
153 Pixel[0]=RangeColorChannel(RenderingColor.B);
154 Pixel[1]=RangeColorChannel(RenderingColor.G);
155 Pixel[2]=RangeColorChannel(RenderingColor.R);
156 }
157 Information->OnRendering(Buffer,Y+1);
158 }
159 Information->OnFinished(Buffer);
160 }
posted on 2009-01-22 06:02
陈梓瀚(vczh) 阅读(2198)
评论(2) 编辑 收藏 引用 所属分类:
3D