Skip to content

Commit

Permalink
Fix tangent issue
Browse files Browse the repository at this point in the history
Script sync from SHA: 43b04bdebdabccb8cf6ad4849a62138f3508fe60
  • Loading branch information
mklefrancois committed Oct 15, 2024
1 parent 96492c5 commit 621f123
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ set(RAPIDJSON_INCLUDE_DIR ${RapidJSON_SOURCE_DIR}/rapidjson-1.1.0/include/rapidj

#####################################################################################
# Adding DRACO if selected
if(POLICY CMP0148)
cmake_policy(SET CMP0148 OLD)
endif()
option(USE_DRACO "Use Draco for compression" OFF)
include(cmake/draco.cmake)
if(USE_DRACO)
Expand Down
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,3 +337,29 @@ The Nvml is a tool that allows to see the status of the GPU. It is possible to s
### Tangent Space

There is a tangent space tool that allows to fix or to recreate the tangent space of the model. This is useful when the normal map is not looking right or there are errors with the tangents in the scene.

## Utilities

### gltf-material-modifier.py

Modify materials in a GLTF file and optionally reorient the scene from Z-up to Y-up.

```
usage: gltf-material-modifier.py [-h] [--metallic METALLIC] [--roughness ROUGHNESS] [--override] [--reorient]
input_file output_file
```

positional arguments:
```
input_file Path to the input GLTF file.
output_file Path to save the modified GLTF file.
```

options:
```
-h, --help show this help message and exit
--metallic METALLIC Set the metallic factor (default: 0.1).
--roughness ROUGHNESS Set the roughness factor (default: 0.1).
--override Override existing material values if set.
--reorient Reorient the scene from Z-up to Y-up.
```
5 changes: 3 additions & 2 deletions shaders/get_hit.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ HitState getHitState(in RenderPrimitive renderPrim, // Buffer containing al

// Normal
hit.nrm = hit.geonrm;
vec3 N = Ng;
if(hasVertexNormal(renderPrim))
{
vec3 N = getInterpolatedVertexNormal(renderPrim, triangleIndex, barycentrics);
N = getInterpolatedVertexNormal(renderPrim, triangleIndex, barycentrics);
hit.nrm = normalize(vec3(N * worldToObject));
}

Expand All @@ -69,7 +70,7 @@ HitState getHitState(in RenderPrimitive renderPrim, // Buffer containing al
}
else
{
vec4 t = makeFastTangent(hit.nrm);
vec4 t = makeFastTangent(N);
tng[0] = t;
tng[1] = t;
tng[2] = t;
Expand Down
2 changes: 1 addition & 1 deletion shaders/pathtrace.comp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
HitPayload hitPayload; // Global hit payload

layout(local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE) in;
#include "rt_payload.h"
#include "rt_layout.h"

#include "nvvkhl/shaders/pbr_mat_eval.h" // Need texturesMap[]
#include "nvvkhl/shaders/hdr_env_sampling.h" // nedd envSamplingData[]
Expand Down
2 changes: 1 addition & 1 deletion shaders/pathtrace.rahit.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include "payload.h"

layout(location = 0) rayPayloadInEXT HitPayload hitPayload;
#include "rt_payload.h"
#include "rt_layout.h"


#include "nvvkhl/shaders/pbr_mat_eval.h" // Need texturesMap[]
Expand Down
2 changes: 1 addition & 1 deletion shaders/pathtrace.rgen.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

layout(location = 0) rayPayloadEXT HitPayload hitPayload;

#include "rt_payload.h"
#include "rt_layout.h"

#include "nvvkhl/shaders/pbr_mat_eval.h" // Need texturesMap[]
#include "nvvkhl/shaders/hdr_env_sampling.h" // nedd envSamplingData[]
Expand Down
2 changes: 1 addition & 1 deletion shaders/raster.frag.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ void main()
for(int i = 0; i < frameInfo.nbLights; i++)
{
Light light = frameInfo.light[i];
LightContrib lightContrib = singleLightContribution(light, hit.pos, pbrMat.N, -worldRayDirection);
LightContrib lightContrib = singleLightContribution(light, hit.pos, pbrMat.N);

BsdfEvaluateData evalData;
evalData.k1 = -worldRayDirection;
Expand Down
4 changes: 2 additions & 2 deletions shaders/rt_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ vec3 sampleLights(in vec3 pos, vec3 normal, in vec3 worldRayDirection, inout uin
{
int lightIndex = min(int(rand(seed) * sceneDesc.numLights), sceneDesc.numLights - 1);
Light light = RenderLightBuf(sceneDesc.lightAddress)._[lightIndex];
LightContrib contrib = singleLightContribution(light, pos, normal, worldRayDirection, vec2(rand(seed), rand(seed)));
LightContrib contrib = singleLightContribution(light, pos, normal, vec2(rand(seed), rand(seed)));
lightDir = -contrib.incidentVector;
lightPdf = (1.0 / sceneDesc.numLights) * lightWeight;
lightRadiance = contrib.intensity / lightPdf;
Expand Down Expand Up @@ -296,7 +296,7 @@ SampleResult pathTrace(Ray r, inout uint seed)
else
{
// Continue path
bool isSpecular = (sampleData.event_type & BSDF_EVENT_SPECULAR) != 0;
bool isSpecular = (sampleData.event_type & BSDF_EVENT_IMPULSE) != 0;
bool isTransmission = (sampleData.event_type & BSDF_EVENT_TRANSMISSION) != 0;

vec3 offsetDir = dot(r.direction, hit.geonrm) > 0 ? hit.geonrm : -hit.geonrm;
Expand Down
File renamed without changes.
91 changes: 91 additions & 0 deletions utils/gltf-material-modifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import json
import argparse
import math
import logging

NINETY_DEG_X_ROTATION = [math.sqrt(0.5), 0, 0, math.sqrt(0.5)]

def reorient_scene(gltf_data):
if not gltf_data.get('scenes') or not gltf_data['scenes'][0].get('nodes'):
logging.warning("No valid scene or nodes found in the glTF file.")
return gltf_data

scene = gltf_data['scenes'][0]

if len(scene['nodes']) == 1:
root_node = gltf_data['nodes'][scene['nodes'][0]]
if 'rotation' in root_node:
logging.info("Applying rotation to existing root node.")
root_node['rotation'] = multiply_quaternions(root_node['rotation'], NINETY_DEG_X_ROTATION)
else:
root_node['rotation'] = NINETY_DEG_X_ROTATION
else:
logging.info("Creating new root node for reorientation.")
new_root = {
"name": "ReorientedRoot",
"rotation": NINETY_DEG_X_ROTATION,
"children": scene['nodes']
}
scene['nodes'] = [len(gltf_data['nodes'])]
gltf_data['nodes'].append(new_root)

return gltf_data

def multiply_quaternions(q1, q2):
return [
q1[0]*q2[0] - q1[1]*q2[1] - q1[2]*q2[2] - q1[3]*q2[3],
q1[0]*q2[1] + q1[1]*q2[0] + q1[2]*q2[3] - q1[3]*q2[2],
q1[0]*q2[2] - q1[1]*q2[3] + q1[2]*q2[0] + q1[3]*q2[1],
q1[0]*q2[3] + q1[1]*q2[2] - q1[2]*q2[1] + q1[3]*q2[0]
]

def modify_gltf(input_file, output_file, metallic_factor, roughness_factor, override, reorient):
logging.info(f"Reading input file: {input_file}")
try:
with open(input_file, 'r') as f:
gltf_data = json.load(f)
except IOError as e:
logging.error(f"Error reading input file: {e}")
return

if reorient:
logging.info("Reorienting scene...")
gltf_data = reorient_scene(gltf_data)

if 'materials' in gltf_data:
logging.info("Modifying materials...")
for material in gltf_data['materials']:
pbr = material.setdefault('pbrMetallicRoughness', {})
if 'metallicFactor' not in pbr or override:
pbr['metallicFactor'] = max(0, min(1, metallic_factor))
if 'roughnessFactor' not in pbr or override:
pbr['roughnessFactor'] = max(0, min(1, roughness_factor))
else:
logging.warning("No materials found in the glTF file.")

logging.info(f"Writing output file: {output_file}")
try:
with open(output_file, 'w') as f:
json.dump(gltf_data, f, indent=2)
logging.info("Modification complete.")
except IOError as e:
logging.error(f"Error writing output file: {e}")

def main():
parser = argparse.ArgumentParser(description="Modify materials in a GLTF file and optionally reorient the scene.")
parser.add_argument("input_file", help="Path to the input GLTF file")
parser.add_argument("output_file", help="Path to save the modified GLTF file")
parser.add_argument("--metallic", type=float, default=0.1, help="Set the metallic factor (default: 0.1)")
parser.add_argument("--roughness", type=float, default=0.1, help="Set the roughness factor (default: 0.1)")
parser.add_argument("--override", action="store_true", help="Override existing material values if set")
parser.add_argument("--reorient", action="store_true", help="Reorient the scene from Z-up to Y-up")
parser.add_argument("--log", choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'], default='INFO', help="Set the logging level")

args = parser.parse_args()

logging.basicConfig(level=getattr(logging, args.log), format='%(levelname)s: %(message)s')

modify_gltf(args.input_file, args.output_file, args.metallic, args.roughness, args.override, args.reorient)

if __name__ == "__main__":
main()

0 comments on commit 621f123

Please sign in to comment.