Skip to content

Implement the refract HLSL Function #99153

@farzonl

Description

@farzonl
  • Implement refract using HLSL source in hlsl_intrinsics.h
  • Implement the refract SPIR-V target built-in in clang/include/clang/Basic/BuiltinsSPIRV.td
  • Add sema checks for refract to CheckSPIRVBuiltinFunctionCall in clang/lib/Sema/SemaSPIRV.cpp
  • Add codegen for spv refract to EmitSPIRVBuiltinExpr in CGBuiltin.cpp
  • Add codegen tests to clang/test/CodeGenHLSL/builtins/refract.hlsl
  • Add spv codegen test to clang/test/CodeGenSPIRV/Builtins/refract.c
  • Add sema tests to clang/test/SemaHLSL/BuiltIns/refract-errors.hlsl
  • Add spv sema tests to clang/test/SemaSPIRV/BuiltIns/refract-errors.c
  • Create the int_spv_refract intrinsic in IntrinsicsSPIRV.td
  • In SPIRVInstructionSelector.cpp create the refract lowering and map it to int_spv_refract in SPIRVInstructionSelector::selectIntrinsic.
  • Create SPIR-V backend test case in llvm/test/CodeGen/SPIRV/hlsl-intrinsics/refract.ll
  • Check for what OpenCL support is needed.

DirectX

DXIL Opcode DXIL OpName Shader Model Shader Stages
56 Dot4 6.0 ()

SPIR-V

Refract:

Description:

Refract

For the incident vector I and surface normal N, and the ratio of
indices of refraction eta, the result is the refraction vector. The
result is computed by

k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))

if k < 0.0 the result is 0.0

otherwise, the result is eta * I - (eta * dot(N, I) +
sqrt(k)) * N

The input parameters for the incident vector I and the surface normal
N must already be normalized to get the desired results.

The type of I and N must be a scalar or vector with a floating-point
component type.

The type of eta must be a 16-bit or 32-bit floating-point scalar.

Result Type, the type of I, and the type of N must all be the same
type.

Number Operand 1 Operand 2 Operand 3 Operand 4

72

<id>
I

<id>
N

<id>
eta

Test Case(s)

Example 1

//dxc refract_test.hlsl -T lib_6_8 -enable-16bit-types -O0

export float4 fn(float4 p1, float4 p2, float p3) {
    return refract(p1, p2, p3);
}

HLSL:

Returns a refraction vector using an entering ray, a surface normal, and a refraction index.

ret refract(i, n, ?)

Parameters

Item Description
i
[in] A floating-point, ray direction vector.
n
[in] A floating-point, surface normal vector.
?
[in] A floating-point, refraction index scalar.

Return Value

A floating-point, refraction vector. If the angle between the entering ray i and the surface normal n is too great for a given refraction index ?, the return value is (0,0,0).

Type Description

Name Template Type Component Type Size
i vector float any
n vector float same dimension(s) as input i
? scalar float 1
refraction vector vector float same dimension(s) as input i

Minimum Shader Model

This function is supported in the following shader models.

Shader Model Supported
Shader Model 2 (DirectX HLSL) and higher shader models yes
Shader Model 1 (DirectX HLSL) yes (vs_1_1 only)

See also

Intrinsic Functions (DirectX HLSL)

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

Status
Closed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions