-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* rewrite git history for cleaning useless textures and models. Basically, this commit finishes the integration of render-pipeline * remove old pipeline code * update tools * add procedual 3d * drive in 3d scenarios! * cool terrain * default flat terrain * update default daytime * make video * format
- Loading branch information
Showing
921 changed files
with
160,417 additions
and
315 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
# Author: @QuanyiLi. This terrain effect can texture road surface/road line. It is modified from: | ||
# terrain-effect by @tobspr: https://github.com/tobspr/RenderPipeline | ||
# Panda3D shader-terrain example: https://github.com/panda3d/panda3d/tree/master/samples/shader-terrain | ||
# texture splatting @wezu: https://gist.github.com/wezu/3892a0a61ae9ddfe57c0aa3f22825ac0#file-terrain_tex_f-glsl-L49 | ||
|
||
vertex: | ||
inout: | | ||
uniform struct { | ||
sampler2D data_texture; | ||
sampler2D heightfield; | ||
int view_index; | ||
int terrain_size; | ||
int chunk_size; | ||
} ShaderTerrainMesh; | ||
out vec2 terrain_uv; | ||
transform: | | ||
// Terrain data has the layout: | ||
// x: x-pos, y: y-pos, z: size, w: clod | ||
vec4 terrain_data = texelFetch(ShaderTerrainMesh.data_texture, | ||
ivec2(gl_InstanceID, ShaderTerrainMesh.view_index), 0); | ||
// Get initial chunk position in the (0, 0, 0), (1, 1, 0) range | ||
vec3 chunk_position = p3d_Vertex.xyz; | ||
// CLOD implementation | ||
float clod_factor = smoothstep(0, 1, terrain_data.w); | ||
chunk_position.xy -= clod_factor * fract(chunk_position.xy * ShaderTerrainMesh.chunk_size / 2.0) | ||
* 2.0 / ShaderTerrainMesh.chunk_size; | ||
// Scale the chunk | ||
chunk_position *= terrain_data.z * float(ShaderTerrainMesh.chunk_size) | ||
/ float(ShaderTerrainMesh.terrain_size); | ||
chunk_position.z *= ShaderTerrainMesh.chunk_size; | ||
// Offset the chunk, it is important that this happens after the scale | ||
chunk_position.xy += terrain_data.xy / float(ShaderTerrainMesh.terrain_size); | ||
// Compute the terrain UV coordinates | ||
terrain_uv = chunk_position.xy; | ||
// Sample the heightfield and offset the terrain - we do not need to multiply | ||
// the height with anything since the terrain transform is included in the | ||
// model view projection matrix. | ||
chunk_position.z += texture(ShaderTerrainMesh.heightfield, terrain_uv).x; | ||
// Lower the terrain on the borders - this ensures the shadow map is generated | ||
// correctly. | ||
if ( min(terrain_uv.x, terrain_uv.y) < 8.0 / ShaderTerrainMesh.terrain_size || | ||
max(terrain_uv.x, terrain_uv.y) > 1 - 9.0 / ShaderTerrainMesh.terrain_size) { | ||
chunk_position.z = 0; | ||
} | ||
vOutput.position = (p3d_ModelMatrix * vec4(chunk_position, 1)).xyz; | ||
fragment: | ||
defines: | | ||
#define DONT_FETCH_DEFAULT_TEXTURES 0 | ||
#define DONT_SET_MATERIAL_PROPERTIES 1 | ||
inout: | | ||
layout(location=4) in vec2 terrain_uv; | ||
in vec3 vtx_pos; | ||
out vec4 color; | ||
layout(location=5) uniform struct { | ||
sampler2D data_texture; | ||
sampler2D heightfield; | ||
int view_index; | ||
int terrain_size; | ||
int chunk_size; | ||
} ShaderTerrainMesh; | ||
// texture for build road | ||
uniform sampler2D yellow_tex; | ||
uniform sampler2D white_tex; | ||
uniform sampler2D road_tex; | ||
uniform sampler2D road_normal; | ||
uniform sampler2D road_rough; | ||
uniform sampler2D grass_tex; | ||
uniform sampler2D grass_normal; | ||
uniform sampler2D grass_rough; | ||
uniform sampler2D rock_tex; | ||
uniform sampler2D rock_normal; | ||
uniform sampler2D rock_rough; | ||
uniform sampler2D attribute_tex; | ||
material: | | ||
float terrain_ratio = 4.0; | ||
float road_tex_ratio = 32.0 * terrain_ratio; | ||
float grass_tex_ratio = 128.0 * terrain_ratio; | ||
vec4 attri = texture(attribute_tex, terrain_uv*terrain_ratio+0.5); | ||
const float terrain_height = 120.0; | ||
vec3 pixel_size = vec3(1.0, -1.0, 0) / textureSize(ShaderTerrainMesh.heightfield, 0).xxx; | ||
float h_u0 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.yz).x * terrain_height; | ||
float h_u1 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.xz).x * terrain_height; | ||
float h_v0 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.zy).x * terrain_height; | ||
float h_v1 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.zx).x * terrain_height; | ||
vec3 tangent = normalize(vec3(1, 0, h_u1 - h_u0)); | ||
vec3 binormal = normalize(vec3(0, 1, h_v1 - h_v0)); | ||
vec3 normal = normalize(cross(tangent, binormal)); | ||
// normal.x *= -1; | ||
mat3 tbn = mat3(tangent, binormal, normal); | ||
if ((attri.g > 0 || attri.a > 0 || attri.b > 0) && terrain_uv.x>0.375 && terrain_uv.y >0.375 && terrain_uv.x<0.625 && terrain_uv.y<0.625){ | ||
// texture splatting, mixing ratio can be determined via rgba, no grass here | ||
vec3 diffuse = texture(road_tex, terrain_uv * road_tex_ratio).rgb * attri.g; | ||
diffuse += texture(yellow_tex, terrain_uv * road_tex_ratio).rgb * attri.b; | ||
diffuse += texture(white_tex, terrain_uv * road_tex_ratio).rgb * attri.a; | ||
m.shading_model = SHADING_MODEL_DEFAULT; | ||
m.specular_ior = 1.51; | ||
m.metallic = 0.0; | ||
m.roughness = texture(road_rough, terrain_uv * road_tex_ratio).r; | ||
m.shading_model_param0 = 0.0; | ||
m.normal = normalize(texture(road_normal, terrain_uv * road_tex_ratio).rgb*2.0-1.0); | ||
m.basecolor = diffuse.xyz; | ||
m.normal = normalize(tbn * m.normal); | ||
} | ||
else{ | ||
// Material splatting | ||
float height = (h_u0 + h_u1 + h_v0 + h_v1) / (4.0 * terrain_height); // xxx | ||
float slope = 1.0 - normal.z; | ||
float grass = 0.0; | ||
float rock = 0.0; | ||
float snow = 0.0; | ||
{ // Snow | ||
snow = saturate(4.0 * (height-0.49)); | ||
snow *= saturate(pow(saturate(1.0 - slope), 2.0)) * 12.0; | ||
//snow -= 0.6; | ||
//snow *= 0.5; | ||
snow = saturate(snow); | ||
snow = pow(snow, 2.0); | ||
} | ||
{ // Rock | ||
rock = saturate((pow(slope, 1.2) * 12.0 - 0.02) * 4.5); | ||
} | ||
{ // Grass | ||
grass = 1.0 - saturate(rock + snow); | ||
} | ||
// Material definitions | ||
MaterialShaderOutput grass_mat = make_default_material_output(); | ||
grass_mat.basecolor = texture(grass_tex, terrain_uv * grass_tex_ratio).rgb; | ||
grass_mat.roughness = texture(grass_rough, terrain_uv * grass_tex_ratio).r; | ||
grass_mat.normal = texture(grass_normal, terrain_uv * grass_tex_ratio).rgb*2.0-1.0; | ||
grass_mat.specular_ior = 0.; | ||
MaterialShaderOutput rock_mat = make_default_material_output(); | ||
rock_mat.basecolor = texture(rock_tex, terrain_uv * grass_tex_ratio).rgb; | ||
rock_mat.roughness = texture(rock_rough, terrain_uv * grass_tex_ratio).r; | ||
rock_mat.normal = texture(rock_normal, terrain_uv * grass_tex_ratio).rgb*2.0-1.0; | ||
rock_mat.specular_ior = 1.7; | ||
MaterialShaderOutput snow_mat = make_default_material_output(); | ||
snow_mat.basecolor = vec3(0.6, 0.6, 0.9); | ||
snow_mat.roughness = 0.5; | ||
snow_mat.specular_ior = 1.7; | ||
m.basecolor = vec3(0); | ||
m.shading_model = SHADING_MODEL_DEFAULT; | ||
m.specular_ior = 0.0; | ||
m.metallic = 0.0; | ||
m.roughness = 0.0; | ||
m.shading_model_param0 = 0.0; | ||
m.normal = vec3(0); | ||
merge_material_output(m, grass_mat, grass); | ||
merge_material_output(m, rock_mat, rock); | ||
merge_material_output(m, snow_mat, snow); | ||
m.normal = normalize(tbn * m.normal); | ||
} | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Author: Epihaius | ||
# Date: 2019-06-21 | ||
# | ||
# This package contains classes to procedurally create 3D primitives such as | ||
# boxes, spheres and cylinders. | ||
# see: https://github.com/Epihaius/procedural_panda3d_model_primitives for more details | ||
|
||
from .box import BoxMaker | ||
from .cylinder import CylinderMaker | ||
from .cone import ConeMaker | ||
from .sphere import SphereMaker | ||
from .torus import TorusMaker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
# Author: Epihaius | ||
# Date: 2019-06-21 | ||
# | ||
# This module contains a couple of imports and a base class needed for the | ||
# creation of all 3D primitives. | ||
|
||
from panda3d.core import * | ||
from math import pi, sin, cos, acos, atan2, sqrt | ||
import array | ||
|
||
|
||
class ModelMaker: | ||
@property | ||
def segments(self): | ||
return self._segments | ||
|
||
@segments.setter | ||
def segments(self, segments): | ||
self._segments = segments | ||
|
||
@property | ||
def inverted(self): | ||
return self._inverted | ||
|
||
@inverted.setter | ||
def inverted(self, inverted): | ||
self._inverted = inverted | ||
|
||
@property | ||
def vertex_color(self): | ||
return self._vertex_color | ||
|
||
@vertex_color.setter | ||
def vertex_color(self, vertex_color): | ||
self._vertex_color = vertex_color | ||
|
||
@property | ||
def has_uvs(self): | ||
return self._has_uvs | ||
|
||
@has_uvs.setter | ||
def has_uvs(self, has_uvs): | ||
self._has_uvs = has_uvs | ||
|
||
@property | ||
def tex_units(self): | ||
return self._tex_units | ||
|
||
@tex_units.setter | ||
def tex_units(self, tex_units): | ||
self._tex_units = tex_units | ||
|
||
@property | ||
def tex_offset(self): | ||
return self._tex_offset | ||
|
||
@tex_offset.setter | ||
def tex_offset(self, tex_offset): | ||
self._tex_offset = tex_offset | ||
|
||
@property | ||
def tex_rotation(self): | ||
return self._tex_rotation | ||
|
||
@tex_rotation.setter | ||
def tex_rotation(self, tex_rotation): | ||
self._tex_rotation = tex_rotation | ||
|
||
@property | ||
def tex_scale(self): | ||
return self._tex_scale | ||
|
||
@tex_scale.setter | ||
def tex_scale(self, tex_scale): | ||
self._tex_scale = tex_scale | ||
|
||
@property | ||
def vertex_ranges(self): | ||
""" | ||
The ranges of vertex indices for each surface, as a dict of | ||
(start_index, end_index) tuples (empty tuple if the surface | ||
was not created), with end_index not included in the range. | ||
See derived class documentation for available surfaces. | ||
""" | ||
return self._vert_ranges | ||
|
||
def __init__( | ||
self, segments, inverted, vertex_color, has_uvs, tex_units, tex_offset, tex_rotation, tex_scale, surface_ids | ||
): | ||
""" | ||
This class generates model primitives with the given parameters, common to | ||
all primitive types: | ||
segments (dict of ints): | ||
the number of subdivisions of each surface (listed in derived class | ||
documentation); | ||
default = None (use defaults for all surfaces); | ||
inverted (bool): | ||
whether or not the geometry should be rendered inside-out; | ||
default is False; | ||
vertex_color (tuple or None): | ||
the color applied to all vertices (if not specified, the vertex format | ||
of the created geometry will not allow any color data to be set); | ||
default = None; | ||
has_uvs (bool): | ||
whether or not the model should have texture coordinates; | ||
default is True; | ||
tex_units (dict of float tuples): | ||
the texture size (width, height) in object-space units for each | ||
surface (listed in derived class documentation); | ||
default = None; | ||
tex_offset, tex_rotation, tex_scale (dicts of float tuples): | ||
the 2D texture transforms in object-space for each surface | ||
(listed in derived class documentation): | ||
tex_offset: (u offset, v offset); | ||
tex_rotation: angle in degrees; | ||
tex_scale: (u scale, v scale); | ||
default = None. | ||
""" | ||
|
||
self._segments = segments | ||
self._inverted = inverted | ||
self._vertex_color = vertex_color | ||
self._has_uvs = has_uvs | ||
self._tex_units = tex_units | ||
self._tex_offset = tex_offset | ||
self._tex_rotation = tex_rotation | ||
self._tex_scale = tex_scale | ||
self._surface_ids = surface_ids | ||
self._vert_ranges = {s_id: () for s_id in surface_ids} | ||
|
||
def reset(self): | ||
|
||
self._segments = None | ||
self._inverted = False | ||
self._vertex_color = None | ||
self._has_uvs = True | ||
self._tex_units = None | ||
self._tex_offset = None | ||
self._tex_rotation = None | ||
self._tex_scale = None | ||
self._vert_ranges = {s_id: () for s_id in self._surface_ids} | ||
|
||
def _make_flat_shaded(self, indices, verts): | ||
|
||
points = [Point3(verts[i]["pos"]) for i in indices[:3]] | ||
normal = Plane(*points).get_normal() | ||
|
||
for i in indices: | ||
verts[i]["normal"] = normal | ||
|
||
def _average_normals(self, index1, index2, verts): | ||
|
||
normal = (verts[index1]["normal"] + verts[index2]["normal"]).normalized() | ||
verts[index1]["normal"] = normal | ||
verts[index2]["normal"] = normal | ||
|
||
def _get_tex_xform(self, surface_id): | ||
|
||
tex_offset = self._tex_offset | ||
tex_rotation = self._tex_rotation | ||
tex_scale = self._tex_scale | ||
|
||
has_tex_offset = tex_offset and surface_id in tex_offset | ||
has_tex_rot = tex_rotation and surface_id in tex_rotation | ||
has_tex_scale = tex_scale and surface_id in tex_scale | ||
has_tex_xform = has_tex_offset or has_tex_rot or has_tex_scale | ||
|
||
if has_tex_xform: | ||
|
||
mat = Mat3.ident_mat() | ||
|
||
if has_tex_scale: | ||
mat = mat * Mat3.scale_mat(*tex_scale[surface_id]) | ||
if has_tex_rot: | ||
mat = mat * Mat3.rotate_mat(tex_rotation[surface_id]) | ||
if has_tex_offset: | ||
mat = mat * Mat3.translate_mat(*tex_offset[surface_id]) | ||
|
||
return mat |
Oops, something went wrong.