Jump to content

Josh

Staff
  • Posts

    24,155
  • Joined

  • Last visited

Everything posted by Josh

  1. To edit the terrain heightmap on the GPU, I create a small buffer and copy part of the heightmap to this. Then I enable the terrain editor shader and draw this small buffer back onto the same spot on the heightmap buffer: Strict Import leadwerks.ENGINE Import "terrain.bmx" Import "Globals.bmx" Global oldTerrainToolPosition:TVec3=Vec3(-1000) Global terrainfilter:TShader[10] Global terrainchanged:Int Global editterrainaabb:TAABB TTerrain.highresheightmap=1 Function UpdateTerrain(terrain:TTerrain) Local x:Int,z:Int,size:Int If terrainchanged 'terrain.generatecolormap() If terrainchanged=2 terrain.getheightmap() If TerrainSectorAABBUpdate size=Int(Sqr(TerrainSectorAABBUpdate.length)+0.5) For x=0 To size-1 For z=0 To size-1 If TerrainSectorAABBUpdate[x,z] terrain.sector[x,z].UpdateAABB() TerrainSectorAABBUpdate[x,z]=0 EndIf Next Next EndIf If editterrainaabb ForEachEntityInAABBDo(editterrainaabb,callback,terrain,ENTITY_MODEL) terrain.quadtree.root.ForEachLeafInAABBDo(editterrainaabb,func,Null) terrain.quadtree.root.UpdateAABB() EndIf EndIf editterrainaabb=Null terrainchanged=False EndIf Function func(leaf:TQuadTreeLeaf,o:Object) leaf.UpdateInstanceHeights(terrain) EndFunction Function Callback:Int(entity:TEntity,extra:Object) If Int(entity.GetKey("aligntoground")) entity.AlignToTerrain(TTerrain(extra)) EndIf Return 1 EndFunction EndFunction Global TerrainSectorAABBUpdate:Byte[,] Function AddVegetationInstance(terrain:TTerrain,x:Float,z:Float,layer:Int,density:Float,randrotation:Int,randscale:Float,aligntonormal:Int,tilt:Float) Local pitch#,yaw#,dist# Local dir:TVec3 Local roll:Float=0.0 Local mat:TMat4 Local scale:Float Local alignmat:TMat4 If terrain.quadtree.layers[layer]=Null Return If terrain.quadtree.layers[layer].model=Null Return If randrotation mat=TMat4.FromYawPitchRoll(Rnd(0.0,360.0),Rnd(-tilt,tilt),Rnd(-tilt,tilt)) Else 'SeedRnd (mat.ix+mat.iy+mat.iz+mat.jx+mat.jy+mat.jz+mat.kx+mat.ky+mat.kz+mat.tx+mat.ty+mat.tz)*1000.0 mat=TMat4.FromYawPitchRoll(0.0,Rnd(-tilt,tilt),Rnd(-tilt,tilt)) EndIf 'SeedRnd (mat.ix+mat.iy+mat.iz+mat.jx+mat.jy+mat.jz+mat.kx+mat.ky+mat.kz+mat.tx+mat.ty+mat.tz)*1000.0 scale=Rnd(1.0-randscale,1.0+randscale) mat.ix:*scale mat.iy:*scale mat.iz:*scale mat.jx:*scale mat.jy:*scale mat.jz:*scale mat.kx:*scale mat.ky:*scale mat.kz:*scale mat.tx=x'x+x0*density+Rnd(-density*0.5,density*0.5) mat.tz=z'z+z0*density+Rnd(-density*0.5,density*0.5) mat.ty=terrain.GetElevation(mat.tx,mat.tz) If aligntonormal dir=terrain.CalcNormal(x,z) dist#=Sqr(dir.x#*dir.x#+dir.z#*dir.z#) pitch#=ATan2(-dir.y#,dist#) yaw#=ATan2(-dir.x#,dir.z#) If randrotation 'SeedRnd (mat.ix+mat.iy+mat.iz+mat.jx+mat.jy+mat.jz+mat.kx+mat.ky+mat.kz+mat.tx+mat.ty+mat.tz)*1000.0 roll=Rnd(0.0,360.0) EndIf alignmat=TMat4.FromYawPitchRoll(yaw,pitch,roll) alignmat.tx=mat.tx alignmat.ty=mat.ty alignmat.tz=mat.tz mat.ix=-alignmat.ix*scale mat.iy=-alignmat.iy*scale mat.iz=-alignmat.iz*scale mat.jx=alignmat.kx*scale mat.jy=alignmat.ky*scale mat.jz=alignmat.kz*scale mat.kx=alignmat.jx*scale mat.ky=alignmat.jy*scale mat.kz=alignmat.jz*scale If randrotation 'SeedRnd (mat.ix+mat.iy+mat.iz+mat.jx+mat.jy+mat.jz+mat.kx+mat.ky+mat.kz+mat.tx+mat.ty+mat.tz)*1000.0 mat=mat.times(TMat4.FromYawPitchRoll(0.0,Rnd(-tilt,tilt),Rnd(-tilt,tilt))) EndIf EndIf terrain.quadtree.addinstance(mat,layer,density) EndFunction Global toolimage:TTexture Function EditTerrain(terrain:TTerrain,x:Float,z:Float,outerradius:Float,innerradius:Float,editmode:Int=0,strength:Float=1.0,channel:Int=0,flattenheight:Float,toolfloor#=0.0,toolceiling#=1.0) Global toolimagebuffer:TBuffer Global channelmask:Float[4] Local x0:Float,z0:Float,x1:Float,z1:Float Local w:Int,h:Int Local tw:Int,th:Int Local cx:Float,cy:Float Local terrainsize:Float Local buffer:TBuffer Local format:Int Local terrbuffer:TBuffer Local texture:TTexture Local constraints:Float[2] Local i:Int Local scale:Float Local ix:Float=x Local iz:Float=z scenechanged=1 If editmode=4 Local gx0:Int,gy0:Int Local gx1:Int,gy1:Int x=Round(x/terrain.scale.x+0.5)+terrain.resolution/2-1 z=Round(z/terrain.scale.z+0.5)+terrain.resolution/2-1 gx0=x-outerradius gx1=x+outerradius gy0=z-outerradius gy1=z+outerradius gx0=Max(0,gx0) gx0=Min(gx0,terrain.resolution-1) gy0=Max(0,gy0) gy0=Min(gy0,terrain.resolution-1) gx1=Max(0,gx1) gx1=Min(gx1,terrain.resolution-1) gy1=Max(0,gy1) gy1=Min(gy1,terrain.resolution-1) w=(gx1-gx0)/2 For x0=gx0 To gx1 For z0=gy0 To gy1 If strength>0 terrain.SetTileVisibility(x0,z0,0,0) Else terrain.SetTileVisibility(x0,z0,1,0) EndIf Next Next terrain.UpdateVisibilityTexture(gx0,gy0,gx1-gx0+1,gy1-gy0+1) Return EndIf If editmode=5 If Not CurrentVegetationLayer Return 'If Not terrain.quadtree.layers[TerrainVegetationLayer] Return 'If Not terrain.quadtree.layers[TerrainVegetationLayer].model Return 'If SelectedGadgetItem(Gadget_VegetationList)=-1 Return If strength>0.0 'Add instances Local tilt:Float=CurrentVegetationLayer.randomtilt'VegetationTilt[TerrainVegetationLayer] Local density:Float=CurrentVegetationLayer.density'VegetationDensity[TerrainVegetationLayer]'Float(GadgetText(Gadget_VegetationDensity)) For x0=-outerradius/density To outerradius/density For z0=-outerradius/density To outerradius/density If Sqr(x0*density*x0*density+z0*density*z0*density)>outerradius Continue 'SeedRnd x+x0*density+z+z0*density cx=x+x0*density+Rnd(-density*0.5,density*0.5) cy=z+z0*density+Rnd(-density*0.5,density*0.5) AddVegetationInstance(terrain,cx,cy,CurrentVegetationLayer.index,CurrentVegetationLayer.density,CurrentVegetationLayer.randomrotation,CurrentVegetationLayer.randomscale,CurrentVegetationLayer.aligntoterrain,CurrentVegetationLayer.randomtilt) Next GCCollect() Next Else 'Remove instances Local aabb:TAABB=New TAABB aabb.x0=x-outerradius aabb.x1=x+outerradius aabb.y0=-infinity aabb.y1=infinity aabb.z0=z-outerradius aabb.z1=z+outerradius aabb.update() terrain.quadtree.root.ForEachLeafInAABBDo(aabb,func,vec3(x,outerradius,z)) Function func(leaf:TQuadTreeLeaf,o:Object) Local n:Int Local dx:Float,dz:Float Local t:TVec3 Local count:Int t=TVec3(o) count=leaf.instance_count[CurrentVegetationLayer.index] n=0 If count Repeat dx=Abs(leaf.instances[CurrentVegetationLayer.index][n*16+12]-t.x) dz=Abs(leaf.instances[CurrentVegetationLayer.index][n*16+14]-t.z) If Sqr(dx*dx+dz*dz)<t.y leaf.DeleteInstance(n,CurrentVegetationLayer.index) n:-1 count:-1 EndIf If n>=count-1 Exit If count<1 Exit n:+1 Forever EndIf EndFunction EndIf Return EndIf If editmode=1 terrainchanged=1 Else terrainchanged=2 EndIf If Not TerrainSectorAABBUpdate Or TerrainSectorAABBUpdate.length<>terrain.sectors*terrain.sectors TerrainSectorAABBUpdate=New Byte[terrain.sectors,terrain.sectors] EndIf If editmode<>1 terrbuffer=terrain.heightbuffer texture=terrain.heightmap Else terrbuffer=terrain.alphabuffer texture=terrain.alphatexture EndIf x0=Floor((0.5+(x-outerradius+0.5*terrain.scale.x)/(Float(terrain.resolution)*terrain.meterspertile))*(terrain.resolution-1)) x1=Ceil((0.5+(x+outerradius+0.5*terrain.scale.x)/(Float(terrain.resolution)*terrain.meterspertile))*(terrain.resolution-1)) z0=Floor((0.5+(z-outerradius+0.5*terrain.scale.x)/(Float(terrain.resolution)*terrain.meterspertile))*(terrain.resolution-1)) z1=Ceil((0.5+(z+outerradius+0.5*terrain.scale.x)/(Float(terrain.resolution)*terrain.meterspertile))*(terrain.resolution-1)) 'Figure out which sectors are affected and need their AABBs updated (skip for paint edit mode) If editmode<>1 And editmode<>4 And editmode<>5 Local sx0:Int,sx1:Int,sz0:Int,sz1:Int sx0=Floor(x0/Float(terrain.sectorresolution)) sx1=Ceil(x1/Float(terrain.sectorresolution))-1 sz0=Floor(z0/Float(terrain.sectorresolution)) sz1=Ceil(z1/Float(terrain.sectorresolution))-1 If sx0<0 sx0=0 If sz0<0 sz0=0 If sx1>terrain.sectors-1 sx1=terrain.sectors-1 If sz1>terrain.sectors-1 sz1=terrain.sectors-1 For x=sx0 To sx1 For z=sz0 To sz1 TerrainSectorAABBUpdate[x,z]=1 Next Next EndIf 'Create small image If editmode=1 format=TEXTURE_RGBA8 Else If GetGraphicsVendor()=VENDOR_NVIDIA If GetShaderModel()=4 format=TEXTURE_FLOAT32 Else format=TEXTURE_FLOAT Print 1 EndIf Else format=TEXTURE_FLOAT32 EndIf EndIf w=x1-x0+1+1+1 h=z1-z0+1+1+1 tw=Pow2(w,1) th=Pow2(h,1) If tw<2 tw=2 If th<2 th=2 'If tw<64 tw=64 'If th<64 th=64 If toolimage If toolimage.width()<>tw Or toolimage.height()<>th toolimage=Null EndIf EndIf If toolimage If TextureFormat(toolimage)<>format toolimage=Null EndIf If Not toolimage toolimage=CreateTexture(tw,th,format) 'If TextureFormat(toolimage)<>format Notify 1 toolimagebuffer=CreateBuffer(tw,th,BUFFER_COLOR) toolimage.setfilter(TEXFILTER_PIXEL) toolimage.bind() SetColorBuffer(toolimagebuffer,toolimage) EndIf If editmode=1 Select channel Case 0 If strength>0.0 channelmask[0]=-1.0 channelmask[1]=-1.0 channelmask[2]=-1.0 channelmask[3]=-1.0 Else channelmask[0]=0.0 channelmask[1]=0.0 channelmask[2]=0.0 channelmask[3]=0.0 EndIf Case 1 If strength>0.0 channelmask[0]=1.0 channelmask[1]=-1.0 channelmask[2]=-1.0 channelmask[3]=-1.0 Else channelmask[0]=1.0 channelmask[1]=0.0 channelmask[2]=0.0 channelmask[3]=0.0 EndIf Case 2 If strength>0.0 channelmask[0]=0.0 channelmask[1]=1.0 channelmask[2]=-1.0 channelmask[3]=-1.0 Else channelmask[0]=0.0 channelmask[1]=1.0 channelmask[2]=0.0 channelmask[3]=0.0 EndIf Case 3 If strength>0.0 channelmask[0]=0.0 channelmask[1]=0.0 channelmask[2]=1.0 channelmask[3]=-1.0 Else channelmask[0]=0.0 channelmask[1]=0.0 channelmask[2]=1.0 channelmask[3]=0.0 EndIf Case 4 If strength>0.0 channelmask[0]=0.0 channelmask[1]=0.0 channelmask[2]=0.0 channelmask[3]=1.0 Else channelmask[0]=0.0 channelmask[1]=0.0 channelmask[2]=0.0 channelmask[3]=1.0 EndIf EndSelect Else channelmask[0]=1.0 channelmask[1]=1.0 channelmask[2]=1.0 channelmask[3]=1.0 If Not editterrainaabb editterrainaabb=New TAABB editterrainaabb.x0=-infinity editterrainaabb.y0=-infinity editterrainaabb.z0=-infinity editterrainaabb.x1=infinity editterrainaabb.y1=infinity editterrainaabb.z1=infinity EndIf editterrainaabb.x0=Min(editterrainaabb.x0,x-outerradius) editterrainaabb.z0=Min(editterrainaabb.z0,z-outerradius) editterrainaabb.x1=Max(editterrainaabb.x1,x+outerradius) editterrainaabb.z1=Max(editterrainaabb.z1,z+outerradius) EndIf 'Disable heightmap linear filter glActiveTextureARB GL_TEXTURE15 glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST glActiveTextureARB GL_TEXTURE0 'Draw heightmap onto small image SetBuffer(toolimagebuffer) SetShader Null 'Global Texture_Contour:TTexture 'If Not Texture_Contour Texture_Contour=LoadTexture("abstract::crysisocean_DISP.dds") 'BindTexture Texture_Contour,1 SetColor vec4(1) FlipImage(texture,-x0+1.0,-z0+1.0) SetColor vec4(1) SetBuffer(BackBuffer()) terrainsize=(Float(terrain.resolution)*Terrain.meterspertile) ix:-terrain.scale.x*0.5 iz:-1 cx=((ix/terrain.scale.x+0.5*Float(terrain.resolution))/Float(terrain.resolution))+0.5/Float(terrain.resolution) cy=((iz/terrain.scale.z+0.5*Float(terrain.resolution))/Float(terrain.resolution))+0.5/Float(terrain.resolution) 'Load terrain edit shader If Not terrainfilter[editmode] terrainfilter[editmode]=LoadShader("abstract::generic.vert","abstract::terraintool.frag","#define TOOLMODE "+editmode+"~n") EndIf 'Set shader uniforms toolceiling=Min(1.0,toolceiling) toolfloor=Max(0.0,toolfloor) constraints[0]=toolfloor'0'Float(SliderValue(Gadget_TerrainToolFloor)-1)/29.0 constraints[1]=toolceiling'1'Float(SliderValue(Gadget_TerrainToolCeiling)-1)/29.0 If strength>0.0 constraints[0]=0.0 If strength<0.0 constraints[1]=1.0 If editmode>1 constraints[0]=0.0 constraints[1]=1.0 EndIf SetShaderVec2 terrainfilter[editmode],"toolposition",[cx,cy] SetShaderVec2 terrainfilter[editmode],"toolradius",[outerradius/terrain.size,innerradius/terrain.size] SetShaderFloat terrainfilter[editmode],"toolstrength",strength SetShaderFloat terrainfilter[editmode],"flattenheight",flattenheight SetShaderVec2 terrainfilter[editmode],"heightmapsize",[Float(terrain.resolution),Float(terrain.resolution)] SetShaderVec2 terrainfilter[editmode],"imagesize",[Float(tw),Float(th)] SetShaderVec4 terrainfilter[editmode],"channelmask",channelmask SetShaderVec2 terrainfilter[editmode],"constraints",constraints 'Draw the small image onto the heightmap buffer=GetBuffer() SetBuffer(terrbuffer) SetShader terrainfilter[editmode] glCheckError() flipImage(toolimage,x0-1,z0-1) glCheckError() SetBuffer buffer SetShader(Null) 'Update the normals of the edited area If editmode<>1 terrain.UpdateNormals(x0-1,z0-1,w,h) EndIf 'Restore heightmap linear filter glActiveTextureARB GL_TEXTURE15 glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR glActiveTextureARB GL_TEXTURE0 terrain.generatecolormap() EndFunction Function FlipImage(image:TTexture,x,y) image.bind(0) glcolor4f 1,1,1,1 glEnable image.target() gldisable GL_CULL_FACE DrawRect x,BufferHeight(GetBuffer())-y,image.width(),-image.height() glDisable image.target() Function DrawRect(x,y,width,height) glBegin GL_QUADS glTexCoord2f 0.0,0.0 glVertex2i x,y glTexCoord2f 0.0,1.0 glVertex2i x,y+height glTexCoord2f 1.0,1.0 glVertex2i x+width,y+height glTexCoord2f 1.0,0.0 glVertex2i x+width,y glEnd EndFunction EndFunction
  2. I think it looks good. They're using a forward renderer in that shot, which can be good in an outdoors scene with one directional light. However, it doesn't allow for shadow-casting point or spot lights. With MSAA the edges of trees and small objects will look a lot smoother, pretty close to that image. MSAA will be added when the engine is updated to use OpenGL 3.
  3. A 4096 shadowmap size means a texture that is 8192x8192 will be used. Grass shadows are adjusted on a global (options>configuration) and per-layer basis.
  4. Yes you can. Turn off shadows. Left 4 dead uses a combination of static lightmaps and single projected shadows, with vertex colors for lighting of dynamic objects. This is the approach I used to use before version 2.0 came out. I will never again implement a bsp-based engine like this. One consequence of a uniform lighting model like STALKER and Crysis use is that on low-end cards the older engines may actually look better than the newer one with settings lowered. The same was true when HL2 came out; the fixed-function renderer was so simple it looked worse than Quake 3.
  5. Josh

    What's missing?

    It's easier to desaturate a saturated image than saturate a desaturated image.
  6. I don't really care. I can see you are a 2.3 owner, so it doesn't matter to me.
  7. I guess everyone is saying you can if you are willing to learn how, but they also want you to know your chosen genre is one of the most ambitious out there.
  8. Josh

    C# Framewerk

    It may be available within a week.
  9. Josh

    C# Framewerk

    I would wait and not do this right now.
  10. Josh

    12-22-9

    Working to improve the implementation of the code known as framework. It needs to be able to talk to Lua, with all programming languages. I can't really go on documenting the script until this is finalized, so the time to do it is now.
  11. The X1550 actually isn't supported because it can't perform texture lookups in the vertex shader, which is why the terrain maps crashed.
  12. Ah, I think he just used one of their tools to make renders.
  13. Josh

    What's missing?

    On the left is the Aion image resized to 3x3 and upsampled. On the right is yours. The difference is saturation.
  14. Intellectual property is certainly a convention like a patent or trademark is, and not the same as a physical object. However, if you want a market for software to exist, it is necessary to adhere to and enforce this convention.
  15. Directional lights render the scene 16 times??? The directional light texture used is twice the dimensions of the shadowmap size you specify, so the multiplier would be four.
  16. No, this was fixed last week and uploaded.
  17. Not only does piracy result in a loss of potential sales, it also increases my time spent supporting the product, because pirates tend to be some of the stupidest users.
  18. Where are you getting ten from?
  19. There is no reason I know of that Vista should not be able to run 3DWS.
  20. Your performance actually seems pretty good considering the card. You're rendering about 500,000 trees at 30 FPS with dynamic lighting on a GEForce 7? How is that bad? I can't really comment on the load times. It doesn't make sense to me why that would be slow. Perhaps the card has a low memory bandwidth, in which case the best thing would be to lower the texture quality and reload the scene. This is a sort of related topic, although I don't think multithreading would do anything for your performance on this machine: http://blitzmax.com/...php?topic=88306
  21. 4 bytes per pixel x 4096 x 4096 x 6 / 1024 / 1024 = 384 mb.
  22. A 4096 sized shadow map on a point light will use 384 mb of video memory.
  23. That's easy. Render straight to the back buffer with no lighting. It will look terrible, but it will be fast. I'd be interested in hearing some definite framerates on your machine for the editor with one of the included scenes opened, at the default window size.
×
×
  • Create New...